1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 #include "libiberty.h"
29 #include "filenames.h"
32 /* A list of symbols to explicitly strip out, or to keep. A linked
33 list is good enough for a small number from the command line, but
34 this will slow things down a lot if many symbols are being
43 /* A list to support redefine_sym. */
48 struct redefine_node
*next
;
51 static void copy_usage
PARAMS ((FILE *, int));
52 static void strip_usage
PARAMS ((FILE *, int));
53 static flagword parse_flags
PARAMS ((const char *));
54 static struct section_list
*find_section_list
PARAMS ((const char *, boolean
));
55 static void setup_section
PARAMS ((bfd
*, asection
*, PTR
));
56 static void copy_section
PARAMS ((bfd
*, asection
*, PTR
));
57 static void get_sections
PARAMS ((bfd
*, asection
*, PTR
));
58 static int compare_section_lma
PARAMS ((const PTR
, const PTR
));
59 static void add_specific_symbol
PARAMS ((const char *, struct symlist
**));
60 static void add_specific_symbols
PARAMS ((const char *, struct symlist
**));
61 static boolean is_specified_symbol
PARAMS ((const char *, struct symlist
*));
62 static boolean is_strip_section
PARAMS ((bfd
*, asection
*));
63 static unsigned int filter_symbols
64 PARAMS ((bfd
*, bfd
*, asymbol
**, asymbol
**, long));
65 static void mark_symbols_used_in_relocations
PARAMS ((bfd
*, asection
*, PTR
));
66 static void filter_bytes
PARAMS ((char *, bfd_size_type
*));
67 static boolean write_debugging_info
PARAMS ((bfd
*, PTR
, long *, asymbol
***));
68 static void copy_object
PARAMS ((bfd
*, bfd
*));
69 static void copy_archive
PARAMS ((bfd
*, bfd
*, const char *));
71 PARAMS ((const char *, const char *, const char *, const char *));
72 static int strip_main
PARAMS ((int, char **));
73 static int copy_main
PARAMS ((int, char **));
74 static const char *lookup_sym_redefinition
PARAMS((const char *));
75 static void redefine_list_append
PARAMS ((const char *, const char *));
77 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
79 static asymbol
**isympp
= NULL
; /* Input symbols */
80 static asymbol
**osympp
= NULL
; /* Output symbols that survive stripping */
82 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
83 static int copy_byte
= -1;
84 static int interleave
= 4;
86 static boolean verbose
; /* Print file and target names. */
87 static boolean preserve_dates
; /* Preserve input file timestamp. */
88 static int status
= 0; /* Exit status. */
93 STRIP_NONE
, /* don't strip */
94 STRIP_DEBUG
, /* strip all debugger symbols */
95 STRIP_UNNEEDED
, /* strip unnecessary symbols */
96 STRIP_ALL
/* strip all symbols */
99 /* Which symbols to remove. */
100 static enum strip_action strip_symbols
;
105 LOCALS_START_L
, /* discard locals starting with L */
106 LOCALS_ALL
/* discard all locals */
109 /* Which local symbols to remove. Overrides STRIP_ALL. */
110 static enum locals_action discard_locals
;
112 /* What kind of change to perform. */
120 /* Structure used to hold lists of sections and actions to take. */
123 struct section_list
* next
; /* Next section to change. */
124 const char * name
; /* Section name. */
125 boolean used
; /* Whether this entry was used. */
126 boolean remove
; /* Whether to remove this section. */
127 boolean copy
; /* Whether to copy this section. */
128 enum change_action change_vma
;/* Whether to change or set VMA. */
129 bfd_vma vma_val
; /* Amount to change by or set to. */
130 enum change_action change_lma
;/* Whether to change or set LMA. */
131 bfd_vma lma_val
; /* Amount to change by or set to. */
132 boolean set_flags
; /* Whether to set the section flags. */
133 flagword flags
; /* What to set the section flags to. */
136 static struct section_list
*change_sections
;
137 static boolean sections_removed
;
138 static boolean sections_copied
;
140 /* Changes to the start address. */
141 static bfd_vma change_start
= 0;
142 static boolean set_start_set
= false;
143 static bfd_vma set_start
;
145 /* Changes to section addresses. */
146 static bfd_vma change_section_address
= 0;
148 /* Filling gaps between sections. */
149 static boolean gap_fill_set
= false;
150 static bfd_byte gap_fill
= 0;
152 /* Pad to a given address. */
153 static boolean pad_to_set
= false;
154 static bfd_vma pad_to
;
156 /* List of sections to add. */
160 /* Next section to add. */
161 struct section_add
*next
;
162 /* Name of section to add. */
164 /* Name of file holding section contents. */
165 const char *filename
;
168 /* Contents of file. */
170 /* BFD section, after it has been added. */
174 static struct section_add
*add_sections
;
176 /* Whether to convert debugging information. */
178 static boolean convert_debugging
= false;
180 /* Whether to change the leading character in symbol names. */
182 static boolean change_leading_char
= false;
184 /* Whether to remove the leading character from global symbol names. */
186 static boolean remove_leading_char
= false;
188 /* List of symbols to strip, keep, localize, keep-global, weaken,
191 static struct symlist
*strip_specific_list
= NULL
;
192 static struct symlist
*keep_specific_list
= NULL
;
193 static struct symlist
*localize_specific_list
= NULL
;
194 static struct symlist
*keepglobal_specific_list
= NULL
;
195 static struct symlist
*weaken_specific_list
= NULL
;
196 static struct redefine_node
*redefine_sym_list
= NULL
;
198 /* If this is true, we weaken global symbols (set BSF_WEAK). */
200 static boolean weaken
= false;
202 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
204 #define OPTION_ADD_SECTION 150
205 #define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)
206 #define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)
207 #define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)
208 #define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)
209 #define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)
210 #define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)
211 #define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)
212 #define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)
213 #define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
214 #define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)
215 #define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)
216 #define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
217 #define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
218 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
219 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
220 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
221 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
222 #define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)
223 #define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
224 #define OPTION_STRIP_SYMBOLS (OPTION_SREC_FORCES3 + 1)
225 #define OPTION_KEEP_SYMBOLS (OPTION_STRIP_SYMBOLS + 1)
226 #define OPTION_LOCALIZE_SYMBOLS (OPTION_KEEP_SYMBOLS + 1)
227 #define OPTION_KEEPGLOBAL_SYMBOLS (OPTION_LOCALIZE_SYMBOLS + 1)
228 #define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1)
230 /* Options to handle if running as "strip". */
232 static struct option strip_options
[] =
234 {"discard-all", no_argument
, 0, 'x'},
235 {"discard-locals", no_argument
, 0, 'X'},
236 {"format", required_argument
, 0, 'F'}, /* Obsolete */
237 {"help", no_argument
, 0, 'h'},
238 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
239 {"input-target", required_argument
, 0, 'I'},
240 {"keep-symbol", required_argument
, 0, 'K'},
241 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
242 {"output-target", required_argument
, 0, 'O'},
243 {"output-file", required_argument
, 0, 'o'},
244 {"preserve-dates", no_argument
, 0, 'p'},
245 {"remove-section", required_argument
, 0, 'R'},
246 {"strip-all", no_argument
, 0, 's'},
247 {"strip-debug", no_argument
, 0, 'S'},
248 {"strip-unneeded", no_argument
, 0, OPTION_STRIP_UNNEEDED
},
249 {"strip-symbol", required_argument
, 0, 'N'},
250 {"target", required_argument
, 0, 'F'},
251 {"verbose", no_argument
, 0, 'v'},
252 {"version", no_argument
, 0, 'V'},
253 {0, no_argument
, 0, 0}
256 /* Options to handle if running as "objcopy". */
258 static struct option copy_options
[] =
260 {"add-section", required_argument
, 0, OPTION_ADD_SECTION
},
261 {"adjust-start", required_argument
, 0, OPTION_CHANGE_START
},
262 {"adjust-vma", required_argument
, 0, OPTION_CHANGE_ADDRESSES
},
263 {"adjust-section-vma", required_argument
, 0, OPTION_CHANGE_SECTION_ADDRESS
},
264 {"adjust-warnings", no_argument
, 0, OPTION_CHANGE_WARNINGS
},
265 {"binary-architecture", required_argument
, 0, 'B'},
266 {"byte", required_argument
, 0, 'b'},
267 {"change-addresses", required_argument
, 0, OPTION_CHANGE_ADDRESSES
},
268 {"change-leading-char", no_argument
, 0, OPTION_CHANGE_LEADING_CHAR
},
269 {"change-section-address", required_argument
, 0, OPTION_CHANGE_SECTION_ADDRESS
},
270 {"change-section-lma", required_argument
, 0, OPTION_CHANGE_SECTION_LMA
},
271 {"change-section-vma", required_argument
, 0, OPTION_CHANGE_SECTION_VMA
},
272 {"change-start", required_argument
, 0, OPTION_CHANGE_START
},
273 {"change-warnings", no_argument
, 0, OPTION_CHANGE_WARNINGS
},
274 {"debugging", no_argument
, 0, OPTION_DEBUGGING
},
275 {"discard-all", no_argument
, 0, 'x'},
276 {"discard-locals", no_argument
, 0, 'X'},
277 {"only-section", required_argument
, 0, 'j'},
278 {"format", required_argument
, 0, 'F'}, /* Obsolete */
279 {"gap-fill", required_argument
, 0, OPTION_GAP_FILL
},
280 {"help", no_argument
, 0, 'h'},
281 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
282 {"input-target", required_argument
, 0, 'I'},
283 {"interleave", required_argument
, 0, 'i'},
284 {"keep-symbol", required_argument
, 0, 'K'},
285 {"no-adjust-warnings", no_argument
, 0, OPTION_NO_CHANGE_WARNINGS
},
286 {"no-change-warnings", no_argument
, 0, OPTION_NO_CHANGE_WARNINGS
},
287 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
288 {"output-target", required_argument
, 0, 'O'},
289 {"pad-to", required_argument
, 0, OPTION_PAD_TO
},
290 {"preserve-dates", no_argument
, 0, 'p'},
291 {"localize-symbol", required_argument
, 0, 'L'},
292 {"keep-global-symbol", required_argument
, 0, 'G'},
293 {"remove-leading-char", no_argument
, 0, OPTION_REMOVE_LEADING_CHAR
},
294 {"remove-section", required_argument
, 0, 'R'},
295 {"set-section-flags", required_argument
, 0, OPTION_SET_SECTION_FLAGS
},
296 {"set-start", required_argument
, 0, OPTION_SET_START
},
297 {"strip-all", no_argument
, 0, 'S'},
298 {"strip-debug", no_argument
, 0, 'g'},
299 {"strip-unneeded", no_argument
, 0, OPTION_STRIP_UNNEEDED
},
300 {"strip-symbol", required_argument
, 0, 'N'},
301 {"target", required_argument
, 0, 'F'},
302 {"verbose", no_argument
, 0, 'v'},
303 {"version", no_argument
, 0, 'V'},
304 {"weaken", no_argument
, 0, OPTION_WEAKEN
},
305 {"weaken-symbol", required_argument
, 0, 'W'},
306 {"redefine-sym", required_argument
, 0, OPTION_REDEFINE_SYM
},
307 {"srec-len", required_argument
, 0, OPTION_SREC_LEN
},
308 {"srec-forceS3", no_argument
, 0, OPTION_SREC_FORCES3
},
309 {"keep-symbols", required_argument
, 0, OPTION_KEEP_SYMBOLS
},
310 {"strip-symbols", required_argument
, 0, OPTION_STRIP_SYMBOLS
},
311 {"keep-global-symbols", required_argument
, 0, OPTION_KEEPGLOBAL_SYMBOLS
},
312 {"localize-symbols", required_argument
, 0, OPTION_LOCALIZE_SYMBOLS
},
313 {"weaken-symbols", required_argument
, 0, OPTION_WEAKEN_SYMBOLS
},
314 {0, no_argument
, 0, 0}
318 extern char *program_name
;
320 /* This flag distinguishes between strip and objcopy:
321 1 means this is 'strip'; 0 means this is 'objcopy'.
322 -1 means if we should use argv[0] to decide. */
325 /* The maximum length of an S record. This variable is declared in srec.c
326 and can be modified by the --srec-len parameter. */
327 extern unsigned int Chunk
;
329 /* Restrict the generation of Srecords to type S3 only.
330 This variable is declare in bfd/srec.c and can be toggled
331 on by the --srec-forceS3 command line switch. */
332 extern boolean S3Forced
;
334 /* Defined in bfd/binary.c. Used to set architecture of input binary files. */
335 extern enum bfd_architecture bfd_external_binary_architecture
;
338 copy_usage (stream
, exit_status
)
342 fprintf (stream
, _("Usage: %s <switches> in-file [out-file]\n"), program_name
);
343 fprintf (stream
, _(" The switches are:\n"));
344 fprintf (stream
, _("\
345 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
346 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
347 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
348 -F --target <bfdname> Set both input and output format to <bfdname>\n\
349 --debugging Convert debugging information, if possible\n\
350 -p --preserve-dates Copy modified/access timestamps to the output\n\
351 -j --only-section <name> Only copy section <name> into the output\n\
352 -R --remove-section <name> Remove section <name> from the output\n\
353 -S --strip-all Remove all symbol and relocation information\n\
354 -g --strip-debug Remove all debugging symbols\n\
355 --strip-unneeded Remove all symbols not needed by relocations\n\
356 -N --strip-symbol <name> Do not copy symbol <name>\n\
357 -K --keep-symbol <name> Only copy symbol <name>\n\
358 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
359 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
360 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
361 --weaken Force all global symbols to be marked as weak\n\
362 -x --discard-all Remove all non-global symbols\n\
363 -X --discard-locals Remove any compiler-generated symbols\n\
364 -i --interleave <number> Only copy one out of every <number> bytes\n\
365 -b --byte <num> Select byte <num> in every interleaved block\n\
366 --gap-fill <val> Fill gaps between sections with <val>\n\
367 --pad-to <addr> Pad the last section up to address <addr>\n\
368 --set-start <addr> Set the start address to <addr>\n\
369 {--change-start|--adjust-start} <incr>\n\
370 Add <incr> to the start address\n\
371 {--change-addresses|--adjust-vma} <incr>\n\
372 Add <incr> to LMA, VMA and start addresses\n\
373 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
374 Change LMA and VMA of section <name> by <val>\n\
375 --change-section-lma <name>{=|+|-}<val>\n\
376 Change the LMA of section <name> by <val>\n\
377 --change-section-vma <name>{=|+|-}<val>\n\
378 Change the VMA of section <name> by <val>\n\
379 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
380 Warn if a named section does not exist\n\
381 --set-section-flags <name>=<flags>\n\
382 Set section <name>'s properties to <flags>\n\
383 --add-section <name>=<file> Add section <name> found in <file> to output\n\
384 --change-leading-char Force output format's leading character style\n\
385 --remove-leading-char Remove leading character from global symbols\n\
386 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
387 --srec-len <number> Restrict the length of generated Srecords\n\
388 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
389 --strip-symbols <file> -N for all symbols listed in <file>\n\
390 --keep-symbols <file> -K for all symbols listed in <file>\n\
391 --localize-symbols <file> -L for all symbols listed in <file>\n\
392 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
393 --weaken-symbols <file> -W for all symbols listed in <file>\n\
394 -v --verbose List all object files modified\n\
395 -V --version Display this program's version number\n\
396 -h --help Display this output\n\
398 list_supported_targets (program_name
, stream
);
399 if (exit_status
== 0)
400 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
405 strip_usage (stream
, exit_status
)
409 fprintf (stream
, _("Usage: %s <switches> in-file(s)\n"), program_name
);
410 fprintf (stream
, _(" The switches are:\n"));
411 fprintf (stream
, _("\
412 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
413 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
414 -F --target <bfdname> Set both input and output format to <bfdname>\n\
415 -p --preserve-dates Copy modified/access timestamps to the output\n\
416 -R --remove-section <name> Remove section <name> from the output\n\
417 -s --strip-all Remove all symbol and relocation information\n\
418 -g -S --strip-debug Remove all debugging symbols\n\
419 --strip-unneeded Remove all symbols not needed by relocations\n\
420 -N --strip-symbol <name> Do not copy symbol <name>\n\
421 -K --keep-symbol <name> Only copy symbol <name>\n\
422 -x --discard-all Remove all non-global symbols\n\
423 -X --discard-locals Remove any compiler-generated symbols\n\
424 -v --verbose List all object files modified\n\
425 -V --version Display this program's version number\n\
426 -h --help Display this output\n\
427 -o <file> Place stripped output into <file>\n\
430 list_supported_targets (program_name
, stream
);
431 if (exit_status
== 0)
432 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
436 /* Parse section flags into a flagword, with a fatal error if the
437 string can't be parsed. */
451 snext
= strchr (s
, ',');
461 #define PARSE_FLAG(fname,fval) \
462 else if (strncasecmp (fname, s, len) == 0) ret |= fval
463 PARSE_FLAG ("alloc", SEC_ALLOC
);
464 PARSE_FLAG ("load", SEC_LOAD
);
465 PARSE_FLAG ("noload", SEC_NEVER_LOAD
);
466 PARSE_FLAG ("readonly", SEC_READONLY
);
467 PARSE_FLAG ("debug", SEC_DEBUGGING
);
468 PARSE_FLAG ("code", SEC_CODE
);
469 PARSE_FLAG ("data", SEC_DATA
);
470 PARSE_FLAG ("rom", SEC_ROM
);
471 PARSE_FLAG ("share", SEC_SHARED
);
472 PARSE_FLAG ("contents", SEC_HAS_CONTENTS
);
478 copy
= xmalloc (len
+ 1);
479 strncpy (copy
, s
, len
);
481 non_fatal (_("unrecognized section flag `%s'"), copy
);
482 fatal (_("supported flags: %s"),
483 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
493 /* Find and optionally add an entry in the change_sections list. */
495 static struct section_list
*
496 find_section_list (name
, add
)
500 register struct section_list
*p
;
502 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
503 if (strcmp (p
->name
, name
) == 0)
509 p
= (struct section_list
*) xmalloc (sizeof (struct section_list
));
514 p
->change_vma
= CHANGE_IGNORE
;
515 p
->change_lma
= CHANGE_IGNORE
;
518 p
->set_flags
= false;
521 p
->next
= change_sections
;
527 /* Add a symbol to strip_specific_list. */
530 add_specific_symbol (name
, list
)
532 struct symlist
**list
;
534 struct symlist
*tmp_list
;
536 tmp_list
= (struct symlist
*) xmalloc (sizeof (struct symlist
));
537 tmp_list
->name
= name
;
538 tmp_list
->next
= *list
;
542 /* Add symbols listed in `filename' to strip_specific_list. */
544 #define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
545 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
548 add_specific_symbols (filename
, list
)
549 const char *filename
;
550 struct symlist
**list
;
556 unsigned int line_count
;
558 if (stat (filename
, & st
) < 0)
559 fatal (_("cannot stat: %s: %s"), filename
, strerror (errno
));
563 buffer
= (char *) xmalloc (st
.st_size
+ 2);
564 f
= fopen (filename
, FOPEN_RT
);
566 fatal (_("cannot open: %s: %s"), filename
, strerror (errno
));
568 if (fread (buffer
, 1, st
.st_size
, f
) == 0 || ferror (f
))
569 fatal (_("%s: fread failed"), filename
);
572 buffer
[st
.st_size
] = '\n';
573 buffer
[st
.st_size
+ 1] = '\0';
577 for (line
= buffer
; * line
!= '\0'; line
++)
582 int finished
= false;
584 for (eol
= line
;; eol
++)
590 /* Cope with \n\r. */
598 /* Cope with \r\n. */
609 /* Line comment, Terminate the line here, in case a
610 name is present and then allow the rest of the
611 loop to find the real end of the line. */
623 /* A name may now exist somewhere between 'line' and 'eol'.
624 Strip off leading whitespace and trailing whitespace,
625 then add it to the list. */
626 for (name
= line
; IS_WHITESPACE (* name
); name
++)
628 for (name_end
= name
;
629 (! IS_WHITESPACE (* name_end
))
630 && (! IS_LINE_TERMINATOR (* name_end
));
634 if (! IS_LINE_TERMINATOR (* name_end
))
638 for (extra
= name_end
+ 1; IS_WHITESPACE (* extra
); extra
++)
641 if (! IS_LINE_TERMINATOR (* extra
))
642 non_fatal (_("Ignoring rubbish found on line %d of %s"),
643 line_count
, filename
);
649 add_specific_symbol (name
, list
);
651 /* Advance line pointer to end of line. The 'eol ++' in the for
652 loop above will then advance us to the start of the next line. */
658 /* See whether a symbol should be stripped or kept based on
659 strip_specific_list and keep_symbols. */
662 is_specified_symbol (name
, list
)
664 struct symlist
*list
;
666 struct symlist
*tmp_list
;
668 for (tmp_list
= list
; tmp_list
; tmp_list
= tmp_list
->next
)
670 if (strcmp (name
, tmp_list
->name
) == 0)
676 /* See if a section is being removed. */
679 is_strip_section (abfd
, sec
)
680 bfd
*abfd ATTRIBUTE_UNUSED
;
683 struct section_list
*p
;
685 if ((bfd_get_section_flags (abfd
, sec
) & SEC_DEBUGGING
) != 0
686 && (strip_symbols
== STRIP_DEBUG
687 || strip_symbols
== STRIP_UNNEEDED
688 || strip_symbols
== STRIP_ALL
689 || discard_locals
== LOCALS_ALL
690 || convert_debugging
))
693 if (! sections_removed
&& ! sections_copied
)
696 p
= find_section_list (bfd_get_section_name (abfd
, sec
), false);
697 if (sections_removed
&& p
!= NULL
&& p
->remove
)
699 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
704 /* Choose which symbol entries to copy; put the result in OSYMS.
705 We don't copy in place, because that confuses the relocs.
706 Return the number of symbols to print. */
709 filter_symbols (abfd
, obfd
, osyms
, isyms
, symcount
)
712 asymbol
**osyms
, **isyms
;
715 register asymbol
**from
= isyms
, **to
= osyms
;
716 long src_count
= 0, dst_count
= 0;
717 int relocatable
= (abfd
->flags
& (HAS_RELOC
| EXEC_P
| DYNAMIC
))
720 for (; src_count
< symcount
; src_count
++)
722 asymbol
*sym
= from
[src_count
];
723 flagword flags
= sym
->flags
;
724 const char *name
= bfd_asymbol_name (sym
);
728 if (redefine_sym_list
)
730 const char *old_name
, *new_name
;
732 old_name
= bfd_asymbol_name (sym
);
733 new_name
= lookup_sym_redefinition (old_name
);
734 name
= bfd_asymbol_name (sym
) = new_name
;
737 if (change_leading_char
738 && (bfd_get_symbol_leading_char (abfd
)
739 != bfd_get_symbol_leading_char (obfd
))
740 && (bfd_get_symbol_leading_char (abfd
) == '\0'
741 || (name
[0] == bfd_get_symbol_leading_char (abfd
))))
743 if (bfd_get_symbol_leading_char (obfd
) == '\0')
744 name
= bfd_asymbol_name (sym
) = name
+ 1;
749 n
= xmalloc (strlen (name
) + 2);
750 n
[0] = bfd_get_symbol_leading_char (obfd
);
751 if (bfd_get_symbol_leading_char (abfd
) == '\0')
752 strcpy (n
+ 1, name
);
754 strcpy (n
+ 1, name
+ 1);
755 name
= bfd_asymbol_name (sym
) = n
;
759 undefined
= bfd_is_und_section (bfd_get_section (sym
));
761 if (remove_leading_char
762 && ((flags
& BSF_GLOBAL
) != 0
763 || (flags
& BSF_WEAK
) != 0
765 || bfd_is_com_section (bfd_get_section (sym
)))
766 && name
[0] == bfd_get_symbol_leading_char (abfd
))
767 name
= bfd_asymbol_name (sym
) = name
+ 1;
769 if (strip_symbols
== STRIP_ALL
)
771 else if ((flags
& BSF_KEEP
) != 0 /* Used in relocation. */
772 || ((flags
& BSF_SECTION_SYM
) != 0
773 && ((*bfd_get_section (sym
)->symbol_ptr_ptr
)->flags
776 else if (relocatable
/* Relocatable file. */
777 && (flags
& (BSF_GLOBAL
| BSF_WEAK
)) != 0)
779 else if (bfd_decode_symclass (sym
) == 'I')
780 /* Global symbols in $idata sections need to be retained
781 even if relocatable is false. External users of the
782 library containing the $idata section may reference these
785 else if ((flags
& BSF_GLOBAL
) != 0 /* Global symbol. */
786 || (flags
& BSF_WEAK
) != 0
788 || bfd_is_com_section (bfd_get_section (sym
)))
789 keep
= strip_symbols
!= STRIP_UNNEEDED
;
790 else if ((flags
& BSF_DEBUGGING
) != 0) /* Debugging symbol. */
791 keep
= (strip_symbols
!= STRIP_DEBUG
792 && strip_symbols
!= STRIP_UNNEEDED
793 && ! convert_debugging
);
794 else if (bfd_get_section (sym
)->comdat
)
795 /* COMDAT sections store special information in local
796 symbols, so we cannot risk stripping any of them. */
798 else /* Local symbol. */
799 keep
= (strip_symbols
!= STRIP_UNNEEDED
800 && (discard_locals
!= LOCALS_ALL
801 && (discard_locals
!= LOCALS_START_L
802 || ! bfd_is_local_label (abfd
, sym
))));
804 if (keep
&& is_specified_symbol (name
, strip_specific_list
))
806 if (!keep
&& is_specified_symbol (name
, keep_specific_list
))
808 if (keep
&& is_strip_section (abfd
, bfd_get_section (sym
)))
811 if (keep
&& (flags
& BSF_GLOBAL
) != 0
812 && (weaken
|| is_specified_symbol (name
, weaken_specific_list
)))
814 sym
->flags
&=~ BSF_GLOBAL
;
815 sym
->flags
|= BSF_WEAK
;
817 if (keep
&& !undefined
&& (flags
& (BSF_GLOBAL
| BSF_WEAK
))
818 && (is_specified_symbol (name
, localize_specific_list
)
819 || (keepglobal_specific_list
!= NULL
820 && ! is_specified_symbol (name
, keepglobal_specific_list
))))
822 sym
->flags
&= ~(BSF_GLOBAL
| BSF_WEAK
);
823 sym
->flags
|= BSF_LOCAL
;
827 to
[dst_count
++] = sym
;
830 to
[dst_count
] = NULL
;
836 lookup_sym_redefinition (source
)
840 struct redefine_node
*list
;
844 for (list
= redefine_sym_list
; list
!= NULL
; list
= list
->next
)
846 if (strcmp (source
, list
->source
) == 0)
848 result
= list
->target
;
855 /* Add a node to a symbol redefine list */
858 redefine_list_append (source
, target
)
862 struct redefine_node
**p
;
863 struct redefine_node
*list
;
864 struct redefine_node
*new_node
;
866 for (p
= &redefine_sym_list
; (list
= *p
) != NULL
; p
= &list
->next
)
868 if (strcmp (source
, list
->source
) == 0)
870 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
875 if (strcmp (target
, list
->target
) == 0)
877 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
883 new_node
= (struct redefine_node
*) xmalloc (sizeof (struct redefine_node
));
885 new_node
->source
= strdup (source
);
886 new_node
->target
= strdup (target
);
887 new_node
->next
= NULL
;
893 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
897 filter_bytes (memhunk
, size
)
901 char *from
= memhunk
+ copy_byte
, *to
= memhunk
, *end
= memhunk
+ *size
;
903 for (; from
< end
; from
+= interleave
)
905 if (*size
% interleave
> (bfd_size_type
) copy_byte
)
906 *size
= (*size
/ interleave
) + 1;
911 /* Copy object file IBFD onto OBFD. */
914 copy_object (ibfd
, obfd
)
920 asection
**osections
= NULL
;
921 bfd_size_type
*gaps
= NULL
;
922 bfd_size_type max_gap
= 0;
926 if (ibfd
->xvec
->byteorder
!= obfd
->xvec
->byteorder
927 && ibfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
928 && obfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
)
930 fatal (_("Unable to change endianness of input file(s)"));
934 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
935 RETURN_NONFATAL (bfd_get_filename (obfd
));
938 printf (_("copy from %s(%s) to %s(%s)\n"),
939 bfd_get_filename (ibfd
), bfd_get_target (ibfd
),
940 bfd_get_filename (obfd
), bfd_get_target (obfd
));
945 start
= bfd_get_start_address (ibfd
);
946 start
+= change_start
;
948 if (!bfd_set_start_address (obfd
, start
)
949 || !bfd_set_file_flags (obfd
,
950 (bfd_get_file_flags (ibfd
)
951 & bfd_applicable_file_flags (obfd
))))
952 RETURN_NONFATAL (bfd_get_filename (ibfd
));
954 /* Copy architecture of input file to output file */
955 if (!bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
956 bfd_get_mach (ibfd
)))
957 non_fatal (_("Warning: Output file cannot represent architecture %s"),
958 bfd_printable_arch_mach (bfd_get_arch (ibfd
),
959 bfd_get_mach (ibfd
)));
961 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
962 RETURN_NONFATAL (bfd_get_filename (ibfd
));
967 if (osympp
!= isympp
)
970 /* BFD mandates that all output sections be created and sizes set before
971 any output is done. Thus, we traverse all sections multiple times. */
972 bfd_map_over_sections (ibfd
, setup_section
, (void *) obfd
);
974 if (add_sections
!= NULL
)
976 struct section_add
*padd
;
977 struct section_list
*pset
;
979 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
981 padd
->section
= bfd_make_section (obfd
, padd
->name
);
982 if (padd
->section
== NULL
)
984 non_fatal (_("can't create section `%s': %s"),
985 padd
->name
, bfd_errmsg (bfd_get_error ()));
993 if (! bfd_set_section_size (obfd
, padd
->section
, padd
->size
))
994 RETURN_NONFATAL (bfd_get_filename (obfd
));
996 pset
= find_section_list (padd
->name
, false);
1000 if (pset
!= NULL
&& pset
->set_flags
)
1001 flags
= pset
->flags
| SEC_HAS_CONTENTS
;
1003 flags
= SEC_HAS_CONTENTS
| SEC_READONLY
| SEC_DATA
;
1005 if (! bfd_set_section_flags (obfd
, padd
->section
, flags
))
1006 RETURN_NONFATAL (bfd_get_filename (obfd
));
1010 if (pset
->change_vma
!= CHANGE_IGNORE
)
1011 if (! bfd_set_section_vma (obfd
, padd
->section
, pset
->vma_val
))
1012 RETURN_NONFATAL (bfd_get_filename (obfd
));
1014 if (pset
->change_lma
!= CHANGE_IGNORE
)
1016 padd
->section
->lma
= pset
->lma_val
;
1018 if (! bfd_set_section_alignment
1019 (obfd
, padd
->section
,
1020 bfd_section_alignment (obfd
, padd
->section
)))
1021 RETURN_NONFATAL (bfd_get_filename (obfd
));
1028 if (gap_fill_set
|| pad_to_set
)
1033 /* We must fill in gaps between the sections and/or we must pad
1034 the last section to a specified address. We do this by
1035 grabbing a list of the sections, sorting them by VMA, and
1036 increasing the section sizes as required to fill the gaps.
1037 We write out the gap contents below. */
1039 c
= bfd_count_sections (obfd
);
1040 osections
= (asection
**) xmalloc (c
* sizeof (asection
*));
1042 bfd_map_over_sections (obfd
, get_sections
, (void *) &set
);
1044 qsort (osections
, c
, sizeof (asection
*), compare_section_lma
);
1046 gaps
= (bfd_size_type
*) xmalloc (c
* sizeof (bfd_size_type
));
1047 memset (gaps
, 0, c
* sizeof (bfd_size_type
));
1051 for (i
= 0; i
< c
- 1; i
++)
1055 bfd_vma gap_start
, gap_stop
;
1057 flags
= bfd_get_section_flags (obfd
, osections
[i
]);
1058 if ((flags
& SEC_HAS_CONTENTS
) == 0
1059 || (flags
& SEC_LOAD
) == 0)
1062 size
= bfd_section_size (obfd
, osections
[i
]);
1063 gap_start
= bfd_section_lma (obfd
, osections
[i
]) + size
;
1064 gap_stop
= bfd_section_lma (obfd
, osections
[i
+ 1]);
1065 if (gap_start
< gap_stop
)
1067 if (! bfd_set_section_size (obfd
, osections
[i
],
1068 size
+ (gap_stop
- gap_start
)))
1070 non_fatal (_("Can't fill gap after %s: %s"),
1071 bfd_get_section_name (obfd
, osections
[i
]),
1072 bfd_errmsg (bfd_get_error ()));
1076 gaps
[i
] = gap_stop
- gap_start
;
1077 if (max_gap
< gap_stop
- gap_start
)
1078 max_gap
= gap_stop
- gap_start
;
1088 lma
= bfd_section_lma (obfd
, osections
[c
- 1]);
1089 size
= bfd_section_size (obfd
, osections
[c
- 1]);
1090 if (lma
+ size
< pad_to
)
1092 if (! bfd_set_section_size (obfd
, osections
[c
- 1],
1095 non_fatal (_("Can't add padding to %s: %s"),
1096 bfd_get_section_name (obfd
, osections
[c
- 1]),
1097 bfd_errmsg (bfd_get_error ()));
1102 gaps
[c
- 1] = pad_to
- (lma
+ size
);
1103 if (max_gap
< pad_to
- (lma
+ size
))
1104 max_gap
= pad_to
- (lma
+ size
);
1110 /* Symbol filtering must happen after the output sections have
1111 been created, but before their contents are set. */
1113 symsize
= bfd_get_symtab_upper_bound (ibfd
);
1115 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1117 osympp
= isympp
= (asymbol
**) xmalloc (symsize
);
1118 symcount
= bfd_canonicalize_symtab (ibfd
, isympp
);
1120 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1122 if (convert_debugging
)
1123 dhandle
= read_debugging_info (ibfd
, isympp
, symcount
);
1125 if (strip_symbols
== STRIP_DEBUG
1126 || strip_symbols
== STRIP_ALL
1127 || strip_symbols
== STRIP_UNNEEDED
1128 || discard_locals
!= LOCALS_UNDEF
1129 || strip_specific_list
!= NULL
1130 || keep_specific_list
!= NULL
1131 || localize_specific_list
!= NULL
1132 || keepglobal_specific_list
!= NULL
1133 || weaken_specific_list
!= NULL
1136 || convert_debugging
1137 || change_leading_char
1138 || remove_leading_char
1139 || redefine_sym_list
1142 /* Mark symbols used in output relocations so that they
1143 are kept, even if they are local labels or static symbols.
1145 Note we iterate over the input sections examining their
1146 relocations since the relocations for the output sections
1147 haven't been set yet. mark_symbols_used_in_relocations will
1148 ignore input sections which have no corresponding output
1150 if (strip_symbols
!= STRIP_ALL
)
1151 bfd_map_over_sections (ibfd
,
1152 mark_symbols_used_in_relocations
,
1154 osympp
= (asymbol
**) xmalloc ((symcount
+ 1) * sizeof (asymbol
*));
1155 symcount
= filter_symbols (ibfd
, obfd
, osympp
, isympp
, symcount
);
1158 if (convert_debugging
&& dhandle
!= NULL
)
1160 if (! write_debugging_info (obfd
, dhandle
, &symcount
, &osympp
))
1167 bfd_set_symtab (obfd
, osympp
, symcount
);
1169 /* This has to happen after the symbol table has been set. */
1170 bfd_map_over_sections (ibfd
, copy_section
, (void *) obfd
);
1172 if (add_sections
!= NULL
)
1174 struct section_add
*padd
;
1176 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
1178 if (! bfd_set_section_contents (obfd
, padd
->section
,
1179 (PTR
) padd
->contents
,
1181 (bfd_size_type
) padd
->size
))
1182 RETURN_NONFATAL (bfd_get_filename (obfd
));
1186 if (gap_fill_set
|| pad_to_set
)
1191 /* Fill in the gaps. */
1195 buf
= (bfd_byte
*) xmalloc (max_gap
);
1196 memset (buf
, gap_fill
, (size_t) max_gap
);
1198 c
= bfd_count_sections (obfd
);
1199 for (i
= 0; i
< c
; i
++)
1207 off
= bfd_section_size (obfd
, osections
[i
]) - left
;
1217 if (! bfd_set_section_contents (obfd
, osections
[i
], buf
,
1219 RETURN_NONFATAL (bfd_get_filename (obfd
));
1228 /* Allow the BFD backend to copy any private data it understands
1229 from the input BFD to the output BFD. This is done last to
1230 permit the routine to look at the filtered symbol table, which is
1231 important for the ECOFF code at least. */
1232 if (!bfd_copy_private_bfd_data (ibfd
, obfd
))
1234 non_fatal (_("%s: error copying private BFD data: %s"),
1235 bfd_get_filename (obfd
),
1236 bfd_errmsg (bfd_get_error ()));
1242 /* Read each archive element in turn from IBFD, copy the
1243 contents to temp file, and keep the temp file handle. */
1246 copy_archive (ibfd
, obfd
, output_target
)
1249 const char *output_target
;
1253 struct name_list
*next
;
1257 bfd
**ptr
= &obfd
->archive_head
;
1259 char *dir
= make_tempname (bfd_get_filename (obfd
));
1261 /* Make a temp directory to hold the contents. */
1262 #if defined (_WIN32) && !defined (__CYGWIN32__)
1263 if (mkdir (dir
) != 0)
1265 if (mkdir (dir
, 0700) != 0)
1268 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1269 dir
, strerror (errno
));
1271 obfd
->has_armap
= ibfd
->has_armap
;
1275 this_element
= bfd_openr_next_archived_file (ibfd
, NULL
);
1276 while (!status
&& this_element
!= (bfd
*) NULL
)
1278 /* Create an output file for this member. */
1279 char *output_name
= concat (dir
, "/", bfd_get_filename (this_element
),
1281 bfd
*output_bfd
= bfd_openw (output_name
, output_target
);
1284 int stat_status
= 0;
1288 stat_status
= bfd_stat_arch_elt (this_element
, &buf
);
1289 if (stat_status
!= 0)
1290 non_fatal (_("internal stat error on %s"),
1291 bfd_get_filename (this_element
));
1294 l
= (struct name_list
*) xmalloc (sizeof (struct name_list
));
1295 l
->name
= output_name
;
1299 if (output_bfd
== (bfd
*) NULL
)
1300 RETURN_NONFATAL (output_name
);
1302 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1303 RETURN_NONFATAL (bfd_get_filename (obfd
));
1305 if (bfd_check_format (this_element
, bfd_object
) == true)
1306 copy_object (this_element
, output_bfd
);
1308 if (!bfd_close (output_bfd
))
1310 bfd_nonfatal (bfd_get_filename (output_bfd
));
1311 /* Error in new object file. Don't change archive. */
1315 if (preserve_dates
&& stat_status
== 0)
1316 set_times (output_name
, &buf
);
1318 /* Open the newly output file and attach to our list. */
1319 output_bfd
= bfd_openr (output_name
, output_target
);
1321 l
->obfd
= output_bfd
;
1324 ptr
= &output_bfd
->next
;
1326 last_element
= this_element
;
1328 this_element
= bfd_openr_next_archived_file (ibfd
, last_element
);
1330 bfd_close (last_element
);
1332 *ptr
= (bfd
*) NULL
;
1334 if (!bfd_close (obfd
))
1335 RETURN_NONFATAL (bfd_get_filename (obfd
));
1337 if (!bfd_close (ibfd
))
1338 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1340 /* Delete all the files that we opened. */
1341 for (l
= list
; l
!= NULL
; l
= l
->next
)
1343 bfd_close (l
->obfd
);
1349 /* The top-level control. */
1352 copy_file (input_filename
, output_filename
, input_target
, output_target
)
1353 const char *input_filename
;
1354 const char *output_filename
;
1355 const char *input_target
;
1356 const char *output_target
;
1361 /* To allow us to do "strip *" without dying on the first
1362 non-object file, failures are nonfatal. */
1364 ibfd
= bfd_openr (input_filename
, input_target
);
1366 RETURN_NONFATAL (input_filename
);
1368 if (bfd_check_format (ibfd
, bfd_archive
))
1372 /* bfd_get_target does not return the correct value until
1373 bfd_check_format succeeds. */
1374 if (output_target
== NULL
)
1375 output_target
= bfd_get_target (ibfd
);
1377 obfd
= bfd_openw (output_filename
, output_target
);
1379 RETURN_NONFATAL (output_filename
);
1381 copy_archive (ibfd
, obfd
, output_target
);
1383 else if (bfd_check_format_matches (ibfd
, bfd_object
, &matching
))
1387 /* bfd_get_target does not return the correct value until
1388 bfd_check_format succeeds. */
1389 if (output_target
== NULL
)
1390 output_target
= bfd_get_target (ibfd
);
1392 obfd
= bfd_openw (output_filename
, output_target
);
1394 RETURN_NONFATAL (output_filename
);
1396 copy_object (ibfd
, obfd
);
1398 if (!bfd_close (obfd
))
1399 RETURN_NONFATAL (output_filename
);
1401 if (!bfd_close (ibfd
))
1402 RETURN_NONFATAL (input_filename
);
1406 bfd_nonfatal (input_filename
);
1408 if (bfd_get_error () == bfd_error_file_ambiguously_recognized
)
1410 list_matching_formats (matching
);
1418 /* Create a section in OBFD with the same name and attributes
1419 as ISECTION in IBFD. */
1422 setup_section (ibfd
, isection
, obfdarg
)
1427 bfd
*obfd
= (bfd
*) obfdarg
;
1428 struct section_list
*p
;
1436 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
1437 && (strip_symbols
== STRIP_DEBUG
1438 || strip_symbols
== STRIP_UNNEEDED
1439 || strip_symbols
== STRIP_ALL
1440 || discard_locals
== LOCALS_ALL
1441 || convert_debugging
))
1444 p
= find_section_list (bfd_section_name (ibfd
, isection
), false);
1448 if (sections_removed
&& p
!= NULL
&& p
->remove
)
1450 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
1453 osection
= bfd_make_section_anyway (obfd
, bfd_section_name (ibfd
, isection
));
1455 if (osection
== NULL
)
1461 size
= bfd_section_size (ibfd
, isection
);
1463 size
= (size
+ interleave
- 1) / interleave
;
1464 if (! bfd_set_section_size (obfd
, osection
, size
))
1470 vma
= bfd_section_vma (ibfd
, isection
);
1471 if (p
!= NULL
&& p
->change_vma
== CHANGE_MODIFY
)
1473 else if (p
!= NULL
&& p
->change_vma
== CHANGE_SET
)
1476 vma
+= change_section_address
;
1478 if (! bfd_set_section_vma (obfd
, osection
, vma
))
1484 lma
= isection
->lma
;
1485 if ((p
!= NULL
) && p
->change_lma
!= CHANGE_IGNORE
)
1487 if (p
->change_lma
== CHANGE_MODIFY
)
1489 else if (p
->change_lma
== CHANGE_SET
)
1495 lma
+= change_section_address
;
1497 osection
->lma
= lma
;
1499 /* FIXME: This is probably not enough. If we change the LMA we
1500 may have to recompute the header for the file as well. */
1501 if (bfd_set_section_alignment (obfd
,
1503 bfd_section_alignment (ibfd
, isection
))
1506 err
= _("alignment");
1510 flags
= bfd_get_section_flags (ibfd
, isection
);
1511 if (p
!= NULL
&& p
->set_flags
)
1512 flags
= p
->flags
| (flags
& SEC_HAS_CONTENTS
);
1513 if (!bfd_set_section_flags (obfd
, osection
, flags
))
1519 /* This used to be mangle_section; we do here to avoid using
1520 bfd_get_section_by_name since some formats allow multiple
1521 sections with the same name. */
1522 isection
->output_section
= osection
;
1523 isection
->output_offset
= 0;
1525 /* Allow the BFD backend to copy any private data it understands
1526 from the input section to the output section. */
1527 if (!bfd_copy_private_section_data (ibfd
, isection
, obfd
, osection
))
1529 err
= _("private data");
1537 non_fatal (_("%s: section `%s': error in %s: %s"),
1538 bfd_get_filename (ibfd
),
1539 bfd_section_name (ibfd
, isection
),
1540 err
, bfd_errmsg (bfd_get_error ()));
1544 /* Copy the data of input section ISECTION of IBFD
1545 to an output section with the same name in OBFD.
1546 If stripping then don't copy any relocation info. */
1549 copy_section (ibfd
, isection
, obfdarg
)
1554 bfd
*obfd
= (bfd
*) obfdarg
;
1555 struct section_list
*p
;
1562 /* If we have already failed earlier on, do not keep on generating
1567 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
1568 && (strip_symbols
== STRIP_DEBUG
1569 || strip_symbols
== STRIP_UNNEEDED
1570 || strip_symbols
== STRIP_ALL
1571 || discard_locals
== LOCALS_ALL
1572 || convert_debugging
))
1575 p
= find_section_list (bfd_section_name (ibfd
, isection
), false);
1577 if (sections_removed
&& p
!= NULL
&& p
->remove
)
1579 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
1582 osection
= isection
->output_section
;
1583 size
= bfd_get_section_size_before_reloc (isection
);
1585 if (size
== 0 || osection
== 0)
1588 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1590 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1593 bfd_set_reloc (obfd
, osection
, (arelent
**) NULL
, 0);
1596 relpp
= (arelent
**) xmalloc (relsize
);
1597 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, isympp
);
1599 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1601 if (strip_symbols
== STRIP_ALL
)
1603 /* Remove relocations which are not in
1604 keep_strip_specific_list. */
1605 arelent
**temp_relpp
;
1606 long temp_relcount
= 0;
1609 temp_relpp
= (arelent
**) xmalloc (relsize
);
1610 for (i
= 0; i
< relcount
; i
++)
1611 if (is_specified_symbol
1612 (bfd_asymbol_name (*relpp
[i
]->sym_ptr_ptr
),
1613 keep_specific_list
))
1614 temp_relpp
[temp_relcount
++] = relpp
[i
];
1615 relcount
= temp_relcount
;
1619 else if (sections_removed
)
1621 /* Remove relocations which are against symbols
1622 in sections that have been removed, unless
1623 the symbols are going to be preserved. */
1624 arelent
** temp_relpp
;
1626 long temp_relcount
= 0;
1629 temp_relpp
= (arelent
**) xmalloc (relsize
);
1630 for (i
= 0; i
< relcount
; i
++)
1632 sym
= *relpp
[i
]->sym_ptr_ptr
;
1634 /* FIXME: Should we warn about deleted relocs ? */
1635 if (is_specified_symbol (bfd_asymbol_name (sym
),
1637 || bfd_get_output_section (sym
) != NULL
)
1638 temp_relpp
[temp_relcount
++] = relpp
[i
];
1641 relcount
= temp_relcount
;
1646 bfd_set_reloc (obfd
, osection
,
1647 (relcount
== 0 ? (arelent
**) NULL
: relpp
), relcount
);
1650 isection
->_cooked_size
= isection
->_raw_size
;
1651 isection
->reloc_done
= true;
1653 if (bfd_get_section_flags (ibfd
, isection
) & SEC_HAS_CONTENTS
)
1655 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
1657 if (!bfd_get_section_contents (ibfd
, isection
, memhunk
, (file_ptr
) 0,
1659 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1662 filter_bytes (memhunk
, &size
);
1664 if (!bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
1666 RETURN_NONFATAL (bfd_get_filename (obfd
));
1670 else if (p
!= NULL
&& p
->set_flags
&& (p
->flags
& SEC_HAS_CONTENTS
) != 0)
1672 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
1674 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1675 flag--they can just remove the section entirely and add it
1676 back again. However, we do permit them to turn on the
1677 SEC_HAS_CONTENTS flag, and take it to mean that the section
1678 contents should be zeroed out. */
1680 memset (memhunk
, 0, size
);
1681 if (! bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
1683 RETURN_NONFATAL (bfd_get_filename (obfd
));
1688 /* Get all the sections. This is used when --gap-fill or --pad-to is
1692 get_sections (obfd
, osection
, secppparg
)
1693 bfd
*obfd ATTRIBUTE_UNUSED
;
1697 asection
***secppp
= (asection
***) secppparg
;
1699 **secppp
= osection
;
1703 /* Sort sections by VMA. This is called via qsort, and is used when
1704 --gap-fill or --pad-to is used. We force non loadable or empty
1705 sections to the front, where they are easier to ignore. */
1708 compare_section_lma (arg1
, arg2
)
1712 const asection
**sec1
= (const asection
**) arg1
;
1713 const asection
**sec2
= (const asection
**) arg2
;
1714 flagword flags1
, flags2
;
1716 /* Sort non loadable sections to the front. */
1717 flags1
= (*sec1
)->flags
;
1718 flags2
= (*sec2
)->flags
;
1719 if ((flags1
& SEC_HAS_CONTENTS
) == 0
1720 || (flags1
& SEC_LOAD
) == 0)
1722 if ((flags2
& SEC_HAS_CONTENTS
) != 0
1723 && (flags2
& SEC_LOAD
) != 0)
1728 if ((flags2
& SEC_HAS_CONTENTS
) == 0
1729 || (flags2
& SEC_LOAD
) == 0)
1733 /* Sort sections by LMA. */
1734 if ((*sec1
)->lma
> (*sec2
)->lma
)
1736 else if ((*sec1
)->lma
< (*sec2
)->lma
)
1739 /* Sort sections with the same LMA by size. */
1740 if ((*sec1
)->_raw_size
> (*sec2
)->_raw_size
)
1742 else if ((*sec1
)->_raw_size
< (*sec2
)->_raw_size
)
1748 /* Mark all the symbols which will be used in output relocations with
1749 the BSF_KEEP flag so that those symbols will not be stripped.
1751 Ignore relocations which will not appear in the output file. */
1754 mark_symbols_used_in_relocations (ibfd
, isection
, symbolsarg
)
1759 asymbol
**symbols
= (asymbol
**) symbolsarg
;
1764 /* Ignore an input section with no corresponding output section. */
1765 if (isection
->output_section
== NULL
)
1768 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1770 bfd_fatal (bfd_get_filename (ibfd
));
1775 relpp
= (arelent
**) xmalloc (relsize
);
1776 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, symbols
);
1778 bfd_fatal (bfd_get_filename (ibfd
));
1780 /* Examine each symbol used in a relocation. If it's not one of the
1781 special bfd section symbols, then mark it with BSF_KEEP. */
1782 for (i
= 0; i
< relcount
; i
++)
1784 if (*relpp
[i
]->sym_ptr_ptr
!= bfd_com_section_ptr
->symbol
1785 && *relpp
[i
]->sym_ptr_ptr
!= bfd_abs_section_ptr
->symbol
1786 && *relpp
[i
]->sym_ptr_ptr
!= bfd_und_section_ptr
->symbol
)
1787 (*relpp
[i
]->sym_ptr_ptr
)->flags
|= BSF_KEEP
;
1794 /* Write out debugging information. */
1797 write_debugging_info (obfd
, dhandle
, symcountp
, symppp
)
1800 long *symcountp ATTRIBUTE_UNUSED
;
1801 asymbol
***symppp ATTRIBUTE_UNUSED
;
1803 if (bfd_get_flavour (obfd
) == bfd_target_ieee_flavour
)
1804 return write_ieee_debugging_info (obfd
, dhandle
);
1806 if (bfd_get_flavour (obfd
) == bfd_target_coff_flavour
1807 || bfd_get_flavour (obfd
) == bfd_target_elf_flavour
)
1809 bfd_byte
*syms
, *strings
;
1810 bfd_size_type symsize
, stringsize
;
1811 asection
*stabsec
, *stabstrsec
;
1813 if (! write_stabs_in_sections_debugging_info (obfd
, dhandle
, &syms
,
1818 stabsec
= bfd_make_section (obfd
, ".stab");
1819 stabstrsec
= bfd_make_section (obfd
, ".stabstr");
1821 || stabstrsec
== NULL
1822 || ! bfd_set_section_size (obfd
, stabsec
, symsize
)
1823 || ! bfd_set_section_size (obfd
, stabstrsec
, stringsize
)
1824 || ! bfd_set_section_alignment (obfd
, stabsec
, 2)
1825 || ! bfd_set_section_alignment (obfd
, stabstrsec
, 0)
1826 || ! bfd_set_section_flags (obfd
, stabsec
,
1830 || ! bfd_set_section_flags (obfd
, stabstrsec
,
1835 non_fatal (_("%s: can't create debugging section: %s"),
1836 bfd_get_filename (obfd
),
1837 bfd_errmsg (bfd_get_error ()));
1841 /* We can get away with setting the section contents now because
1842 the next thing the caller is going to do is copy over the
1843 real sections. We may someday have to split the contents
1844 setting out of this function. */
1845 if (! bfd_set_section_contents (obfd
, stabsec
, syms
, (file_ptr
) 0,
1847 || ! bfd_set_section_contents (obfd
, stabstrsec
, strings
,
1848 (file_ptr
) 0, stringsize
))
1850 non_fatal (_("%s: can't set debugging section contents: %s"),
1851 bfd_get_filename (obfd
),
1852 bfd_errmsg (bfd_get_error ()));
1859 non_fatal (_("%s: don't know how to write debugging information for %s"),
1860 bfd_get_filename (obfd
), bfd_get_target (obfd
));
1865 strip_main (argc
, argv
)
1869 char *input_target
= NULL
, *output_target
= NULL
;
1870 boolean show_version
= false;
1872 struct section_list
*p
;
1873 char *output_file
= NULL
;
1875 while ((c
= getopt_long (argc
, argv
, "I:O:F:K:N:R:o:sSpdgxXVv",
1876 strip_options
, (int *) 0)) != EOF
)
1881 input_target
= optarg
;
1884 output_target
= optarg
;
1887 input_target
= output_target
= optarg
;
1890 p
= find_section_list (optarg
, true);
1892 sections_removed
= true;
1895 strip_symbols
= STRIP_ALL
;
1899 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1900 strip_symbols
= STRIP_DEBUG
;
1902 case OPTION_STRIP_UNNEEDED
:
1903 strip_symbols
= STRIP_UNNEEDED
;
1906 add_specific_symbol (optarg
, &keep_specific_list
);
1909 add_specific_symbol (optarg
, &strip_specific_list
);
1912 output_file
= optarg
;
1915 preserve_dates
= true;
1918 discard_locals
= LOCALS_ALL
;
1921 discard_locals
= LOCALS_START_L
;
1927 show_version
= true;
1930 break; /* we've been given a long option */
1932 strip_usage (stdout
, 0);
1934 strip_usage (stderr
, 1);
1939 print_version ("strip");
1941 /* Default is to strip all symbols. */
1942 if (strip_symbols
== STRIP_UNDEF
1943 && discard_locals
== LOCALS_UNDEF
1944 && strip_specific_list
== NULL
)
1945 strip_symbols
= STRIP_ALL
;
1947 if (output_target
== (char *) NULL
)
1948 output_target
= input_target
;
1952 || (output_file
!= NULL
&& (i
+ 1) < argc
))
1953 strip_usage (stderr
, 1);
1955 for (; i
< argc
; i
++)
1957 int hold_status
= status
;
1958 struct stat statbuf
;
1963 if (stat (argv
[i
], &statbuf
) < 0)
1965 non_fatal (_("%s: cannot stat: %s"), argv
[i
], strerror (errno
));
1970 if (output_file
!= NULL
)
1971 tmpname
= output_file
;
1973 tmpname
= make_tempname (argv
[i
]);
1976 copy_file (argv
[i
], tmpname
, input_target
, output_target
);
1980 set_times (tmpname
, &statbuf
);
1981 if (output_file
== NULL
)
1982 smart_rename (tmpname
, argv
[i
], preserve_dates
);
1983 status
= hold_status
;
1987 if (output_file
== NULL
)
1995 copy_main (argc
, argv
)
1999 char * binary_architecture
= NULL
;
2000 char *input_filename
= NULL
, *output_filename
= NULL
;
2001 char *input_target
= NULL
, *output_target
= NULL
;
2002 boolean show_version
= false;
2003 boolean change_warn
= true;
2005 struct section_list
*p
;
2006 struct stat statbuf
;
2008 while ((c
= getopt_long (argc
, argv
, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:",
2009 copy_options
, (int *) 0)) != EOF
)
2014 copy_byte
= atoi (optarg
);
2016 fatal (_("byte number must be non-negative"));
2020 binary_architecture
= optarg
;
2024 interleave
= atoi (optarg
);
2026 fatal (_("interleave must be positive"));
2030 case 's': /* "source" - 'I' is preferred */
2031 input_target
= optarg
;
2035 case 'd': /* "destination" - 'O' is preferred */
2036 output_target
= optarg
;
2040 input_target
= output_target
= optarg
;
2044 p
= find_section_list (optarg
, true);
2046 fatal (_("%s both copied and removed"), optarg
);
2048 sections_copied
= true;
2052 p
= find_section_list (optarg
, true);
2054 fatal (_("%s both copied and removed"), optarg
);
2056 sections_removed
= true;
2060 strip_symbols
= STRIP_ALL
;
2064 strip_symbols
= STRIP_DEBUG
;
2067 case OPTION_STRIP_UNNEEDED
:
2068 strip_symbols
= STRIP_UNNEEDED
;
2072 add_specific_symbol (optarg
, &keep_specific_list
);
2076 add_specific_symbol (optarg
, &strip_specific_list
);
2080 add_specific_symbol (optarg
, &localize_specific_list
);
2084 add_specific_symbol (optarg
, &keepglobal_specific_list
);
2088 add_specific_symbol (optarg
, &weaken_specific_list
);
2092 preserve_dates
= true;
2096 discard_locals
= LOCALS_ALL
;
2100 discard_locals
= LOCALS_START_L
;
2108 show_version
= true;
2115 case OPTION_ADD_SECTION
:
2119 struct section_add
*pa
;
2124 s
= strchr (optarg
, '=');
2127 fatal (_("bad format for %s"), "--add-section");
2129 if (stat (s
+ 1, & st
) < 0)
2130 fatal (_("cannot stat: %s: %s"), s
+ 1, strerror (errno
));
2132 pa
= (struct section_add
*) xmalloc (sizeof (struct section_add
));
2135 name
= (char *) xmalloc (len
+ 1);
2136 strncpy (name
, optarg
, len
);
2140 pa
->filename
= s
+ 1;
2142 pa
->size
= st
.st_size
;
2144 pa
->contents
= (bfd_byte
*) xmalloc (pa
->size
);
2145 f
= fopen (pa
->filename
, FOPEN_RB
);
2148 fatal (_("cannot open: %s: %s"), pa
->filename
, strerror (errno
));
2150 if (fread (pa
->contents
, 1, pa
->size
, f
) == 0
2152 fatal (_("%s: fread failed"), pa
->filename
);
2156 pa
->next
= add_sections
;
2161 case OPTION_CHANGE_START
:
2162 change_start
= parse_vma (optarg
, "--change-start");
2165 case OPTION_CHANGE_SECTION_ADDRESS
:
2166 case OPTION_CHANGE_SECTION_LMA
:
2167 case OPTION_CHANGE_SECTION_VMA
:
2172 char *option
= NULL
;
2174 enum change_action what
= CHANGE_IGNORE
;
2178 case OPTION_CHANGE_SECTION_ADDRESS
:
2179 option
= "--change-section-address";
2181 case OPTION_CHANGE_SECTION_LMA
:
2182 option
= "--change-section-lma";
2184 case OPTION_CHANGE_SECTION_VMA
:
2185 option
= "--change-section-vma";
2189 s
= strchr (optarg
, '=');
2192 s
= strchr (optarg
, '+');
2195 s
= strchr (optarg
, '-');
2197 fatal (_("bad format for %s"), option
);
2202 name
= (char *) xmalloc (len
+ 1);
2203 strncpy (name
, optarg
, len
);
2206 p
= find_section_list (name
, true);
2208 val
= parse_vma (s
+ 1, option
);
2212 case '=': what
= CHANGE_SET
; break;
2213 case '-': val
= - val
; /* Drop through. */
2214 case '+': what
= CHANGE_MODIFY
; break;
2219 case OPTION_CHANGE_SECTION_ADDRESS
:
2220 p
->change_vma
= what
;
2224 case OPTION_CHANGE_SECTION_LMA
:
2225 p
->change_lma
= what
;
2229 case OPTION_CHANGE_SECTION_VMA
:
2230 p
->change_vma
= what
;
2237 case OPTION_CHANGE_ADDRESSES
:
2238 change_section_address
= parse_vma (optarg
, "--change-addresses");
2239 change_start
= change_section_address
;
2242 case OPTION_CHANGE_WARNINGS
:
2246 case OPTION_CHANGE_LEADING_CHAR
:
2247 change_leading_char
= true;
2250 case OPTION_DEBUGGING
:
2251 convert_debugging
= true;
2254 case OPTION_GAP_FILL
:
2256 bfd_vma gap_fill_vma
;
2258 gap_fill_vma
= parse_vma (optarg
, "--gap-fill");
2259 gap_fill
= (bfd_byte
) gap_fill_vma
;
2260 if ((bfd_vma
) gap_fill
!= gap_fill_vma
)
2264 sprintf_vma (buff
, gap_fill_vma
);
2266 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2269 gap_fill_set
= true;
2273 case OPTION_NO_CHANGE_WARNINGS
:
2274 change_warn
= false;
2278 pad_to
= parse_vma (optarg
, "--pad-to");
2282 case OPTION_REMOVE_LEADING_CHAR
:
2283 remove_leading_char
= true;
2286 case OPTION_REDEFINE_SYM
:
2288 /* Push this redefinition onto redefine_symbol_list. */
2292 const char *nextarg
;
2293 char *source
, *target
;
2295 s
= strchr (optarg
, '=');
2298 fatal (_("bad format for %s"), "--redefine-sym");
2302 source
= (char *) xmalloc (len
+ 1);
2303 strncpy (source
, optarg
, len
);
2307 len
= strlen (nextarg
);
2308 target
= (char *) xmalloc (len
+ 1);
2309 strcpy (target
, nextarg
);
2311 redefine_list_append (source
, target
);
2318 case OPTION_SET_SECTION_FLAGS
:
2324 s
= strchr (optarg
, '=');
2326 fatal (_("bad format for %s"), "--set-section-flags");
2329 name
= (char *) xmalloc (len
+ 1);
2330 strncpy (name
, optarg
, len
);
2333 p
= find_section_list (name
, true);
2335 p
->set_flags
= true;
2336 p
->flags
= parse_flags (s
+ 1);
2340 case OPTION_SET_START
:
2341 set_start
= parse_vma (optarg
, "--set-start");
2342 set_start_set
= true;
2345 case OPTION_SREC_LEN
:
2346 Chunk
= parse_vma (optarg
, "--srec-len");
2349 case OPTION_SREC_FORCES3
:
2353 case OPTION_STRIP_SYMBOLS
:
2354 add_specific_symbols (optarg
, &strip_specific_list
);
2357 case OPTION_KEEP_SYMBOLS
:
2358 add_specific_symbols (optarg
, &keep_specific_list
);
2361 case OPTION_LOCALIZE_SYMBOLS
:
2362 add_specific_symbols (optarg
, &localize_specific_list
);
2365 case OPTION_KEEPGLOBAL_SYMBOLS
:
2366 add_specific_symbols (optarg
, &keepglobal_specific_list
);
2369 case OPTION_WEAKEN_SYMBOLS
:
2370 add_specific_symbols (optarg
, &weaken_specific_list
);
2374 break; /* we've been given a long option */
2377 copy_usage (stdout
, 0);
2380 copy_usage (stderr
, 1);
2385 print_version ("objcopy");
2387 if (copy_byte
>= interleave
)
2388 fatal (_("byte number must be less than interleave"));
2390 if (optind
== argc
|| optind
+ 2 < argc
)
2391 copy_usage (stderr
, 1);
2393 input_filename
= argv
[optind
];
2394 if (optind
+ 1 < argc
)
2395 output_filename
= argv
[optind
+ 1];
2397 /* Default is to strip no symbols. */
2398 if (strip_symbols
== STRIP_UNDEF
&& discard_locals
== LOCALS_UNDEF
)
2399 strip_symbols
= STRIP_NONE
;
2401 if (output_target
== (char *) NULL
)
2402 output_target
= input_target
;
2404 if (binary_architecture
!= (char *) NULL
)
2406 if (input_target
&& strcmp (input_target
, "binary") == 0)
2408 const bfd_arch_info_type
* temp_arch_info
;
2410 temp_arch_info
= bfd_scan_arch (binary_architecture
);
2412 if (temp_arch_info
!= NULL
)
2413 bfd_external_binary_architecture
= temp_arch_info
->arch
;
2415 fatal (_("architecture %s unknown"), binary_architecture
);
2419 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2420 non_fatal (_(" Argument %s ignored"), binary_architecture
);
2425 if (stat (input_filename
, & statbuf
) < 0)
2426 fatal (_("Cannot stat: %s: %s"), input_filename
, strerror (errno
));
2428 /* If there is no destination file then create a temp and rename
2429 the result into the input. */
2431 if (output_filename
== (char *) NULL
)
2433 char *tmpname
= make_tempname (input_filename
);
2435 copy_file (input_filename
, tmpname
, input_target
, output_target
);
2439 set_times (tmpname
, &statbuf
);
2440 smart_rename (tmpname
, input_filename
, preserve_dates
);
2447 copy_file (input_filename
, output_filename
, input_target
, output_target
);
2448 if (status
== 0 && preserve_dates
)
2449 set_times (output_filename
, &statbuf
);
2454 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
2458 if (p
->change_vma
!= CHANGE_IGNORE
)
2462 sprintf_vma (buff
, p
->vma_val
);
2464 /* xgettext:c-format */
2465 non_fatal (_("%s %s%c0x%s never used"),
2466 "--change-section-vma",
2468 p
->change_vma
== CHANGE_SET
? '=' : '+',
2472 if (p
->change_lma
!= CHANGE_IGNORE
)
2476 sprintf_vma (buff
, p
->lma_val
);
2478 /* xgettext:c-format */
2479 non_fatal (_("%s %s%c0x%s never used"),
2480 "--change-section-lma",
2482 p
->change_lma
== CHANGE_SET
? '=' : '+',
2497 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2498 setlocale (LC_MESSAGES
, "");
2500 bindtextdomain (PACKAGE
, LOCALEDIR
);
2501 textdomain (PACKAGE
);
2503 program_name
= argv
[0];
2504 xmalloc_set_program_name (program_name
);
2506 START_PROGRESS (program_name
, 0);
2508 strip_symbols
= STRIP_UNDEF
;
2509 discard_locals
= LOCALS_UNDEF
;
2512 set_default_bfd_target ();
2516 int i
= strlen (program_name
);
2517 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2518 /* Drop the .exe suffix, if any. */
2519 if (i
> 4 && FILENAME_CMP (program_name
+ i
- 4, ".exe") == 0)
2522 program_name
[i
] = '\0';
2525 is_strip
= (i
>= 5 && FILENAME_CMP (program_name
+ i
- 5, "strip") == 0);
2529 strip_main (argc
, argv
);
2531 copy_main (argc
, argv
);
2533 END_PROGRESS (program_name
);