1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2 Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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.
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.
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
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 static void setup_section ();
26 static void copy_section ();
27 static void mangle_section ();
29 #define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
31 static asymbol
**isympp
= NULL
; /* Input symbols */
32 static asymbol
**osympp
= NULL
; /* Output symbols that survive stripping */
34 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
35 static int copy_byte
= -1;
36 static int interleave
= 4;
38 static boolean verbose
; /* Print file and target names. */
39 static int status
= 0; /* Exit status. */
44 strip_none
, /* don't strip */
45 strip_debug
, /* strip all debugger symbols */
46 strip_all
/* strip all symbols */
49 /* Which symbols to remove. */
50 static enum strip_action strip_symbols
;
55 locals_start_L
, /* discard locals starting with L */
56 locals_all
/* discard all locals */
59 /* Which local symbols to remove. Overrides strip_all. */
60 static enum locals_action discard_locals
;
62 /* Options to handle if running as "strip". */
64 static struct option strip_options
[] =
66 {"discard-all", no_argument
, 0, 'x'},
67 {"discard-locals", no_argument
, 0, 'X'},
68 {"format", required_argument
, 0, 'F'}, /* Obsolete */
69 {"help", no_argument
, 0, 'h'},
70 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
71 {"input-target", required_argument
, 0, 'I'},
72 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
73 {"output-target", required_argument
, 0, 'O'},
74 {"strip-all", no_argument
, 0, 's'},
75 {"strip-debug", no_argument
, 0, 'S'},
76 {"target", required_argument
, 0, 'F'},
77 {"verbose", no_argument
, 0, 'v'},
78 {"version", no_argument
, 0, 'V'},
79 {0, no_argument
, 0, 0}
82 /* Options to handle if running as "objcopy". */
84 static struct option copy_options
[] =
86 {"byte", required_argument
, 0, 'b'},
87 {"discard-all", no_argument
, 0, 'x'},
88 {"discard-locals", no_argument
, 0, 'X'},
89 {"format", required_argument
, 0, 'F'}, /* Obsolete */
90 {"help", no_argument
, 0, 'h'},
91 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
92 {"input-target", required_argument
, 0, 'I'},
93 {"interleave", required_argument
, 0, 'i'},
94 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
95 {"output-target", required_argument
, 0, 'O'},
96 {"strip-all", no_argument
, 0, 'S'},
97 {"strip-debug", no_argument
, 0, 'g'},
98 {"target", required_argument
, 0, 'F'},
99 {"verbose", no_argument
, 0, 'v'},
100 {"version", no_argument
, 0, 'V'},
101 {0, no_argument
, 0, 0}
105 extern char *program_name
;
106 extern char *program_version
;
108 /* This flag distinguishes between strip and objcopy:
109 1 means this is 'strip'; 0 means this is 'objcopy'.
110 -1 means if we should use argv[0] to decide. */
115 copy_usage (stream
, status
)
120 Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
121 [-i interleave] [--interleave=interleave] [--byte=byte]\n\
122 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
123 [--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
124 [--verbose] [--version] [--help] in-file [out-file]\n",
130 strip_usage (stream
, status
)
135 Usage: %s [-vVsSgxX] [-I bfdname] [-O bfdname] [-F bfdname]\n\
136 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
137 [--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
138 [--verbose] [--version] [--help] file...\n",
144 /* Return the name of a temporary file in the same directory as FILENAME. */
147 make_tempname (filename
)
150 static char template[] = "stXXXXXX";
152 char *slash
= strrchr (filename
, '/');
154 if (slash
!= (char *) NULL
)
157 tmpname
= xmalloc (strlen (filename
) + sizeof (template) + 1);
158 strcpy (tmpname
, filename
);
159 strcat (tmpname
, "/");
160 strcat (tmpname
, template);
166 tmpname
= xmalloc (sizeof (template));
167 strcpy (tmpname
, template);
173 /* Choose which symbol entries to copy; put the result in OSYMS.
174 We don't copy in place, because that confuses the relocs.
175 Return the number of symbols to print. */
178 filter_symbols (abfd
, osyms
, isyms
, symcount
)
180 asymbol
**osyms
, **isyms
;
181 unsigned long symcount
;
183 register asymbol
**from
= isyms
, **to
= osyms
;
184 char locals_prefix
= bfd_get_symbol_leading_char (abfd
) == '_' ? 'L' : '.';
185 unsigned int src_count
= 0, dst_count
= 0;
187 for (; src_count
< symcount
; src_count
++)
189 asymbol
*sym
= from
[src_count
];
190 flagword flags
= sym
->flags
;
193 if ((flags
& BSF_GLOBAL
) /* Keep if external. */
194 || bfd_get_section (sym
) == &bfd_und_section
195 || bfd_is_com_section (bfd_get_section (sym
)))
197 else if ((flags
& BSF_DEBUGGING
) != 0) /* Debugging symbol. */
198 keep
= strip_symbols
!= strip_debug
;
199 else /* Local symbol. */
200 keep
= discard_locals
!= locals_all
201 && (discard_locals
!= locals_start_L
||
202 bfd_asymbol_name (sym
)[0] != locals_prefix
);
204 to
[dst_count
++] = sym
;
210 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
214 filter_bytes (memhunk
, size
)
218 char *from
= memhunk
+ copy_byte
, *to
= memhunk
, *end
= memhunk
+ *size
;
220 for (; from
< end
; from
+= interleave
)
225 /* Copy object file IBFD onto OBFD. */
228 copy_object (ibfd
, obfd
)
232 unsigned int symcount
;
234 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
236 nonfatal (bfd_get_filename (obfd
));
240 printf ("copy from %s(%s) to %s(%s)\n",
241 bfd_get_filename(ibfd
), bfd_get_target(ibfd
),
242 bfd_get_filename(obfd
), bfd_get_target(obfd
));
244 if (!bfd_set_start_address (obfd
, bfd_get_start_address (ibfd
))
245 || !bfd_set_file_flags (obfd
,
246 (bfd_get_file_flags (ibfd
)
247 & bfd_applicable_file_flags (obfd
))))
249 nonfatal (bfd_get_filename (ibfd
));
252 /* Copy architecture of input file to output file */
253 if (!bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
254 bfd_get_mach (ibfd
)))
256 fprintf (stderr
, "Output file cannot represent architecture %s\n",
257 bfd_printable_arch_mach (bfd_get_arch (ibfd
),
258 bfd_get_mach (ibfd
)));
260 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
262 nonfatal (bfd_get_filename(ibfd
));
267 if (osympp
!= isympp
)
270 if (strip_symbols
== strip_all
&& discard_locals
== locals_undef
)
272 osympp
= isympp
= NULL
;
277 osympp
= isympp
= (asymbol
**) xmalloc (get_symtab_upper_bound (ibfd
));
278 symcount
= bfd_canonicalize_symtab (ibfd
, isympp
);
280 if (strip_symbols
== strip_debug
|| discard_locals
!= locals_undef
)
282 osympp
= (asymbol
**) xmalloc (symcount
* sizeof (asymbol
*));
283 symcount
= filter_symbols (ibfd
, osympp
, isympp
, symcount
);
287 bfd_set_symtab (obfd
, osympp
, symcount
);
289 /* bfd mandates that all output sections be created and sizes set before
290 any output is done. Thus, we traverse all sections multiple times. */
291 bfd_map_over_sections (ibfd
, setup_section
, (void *) obfd
);
292 bfd_map_over_sections (ibfd
, copy_section
, (void *) obfd
);
293 bfd_map_over_sections (ibfd
, mangle_section
, (void *) obfd
);
302 size_t size
= strlen (a
) + strlen (b
) + strlen (c
);
303 char *r
= xmalloc (size
+ 1);
311 /* Read each archive element in turn from IBFD, copy the
312 contents to temp file, and keep the temp file handle. */
315 copy_archive (ibfd
, obfd
, output_target
)
320 bfd
**ptr
= &obfd
->archive_head
;
322 char *dir
= cat ("./#", make_tempname (""), "cd");
324 /* Make a temp directory to hold the contents. */
326 obfd
->has_armap
= ibfd
->has_armap
;
328 this_element
= bfd_openr_next_archived_file (ibfd
, NULL
);
329 ibfd
->archive_head
= this_element
;
330 while (this_element
!= (bfd
*) NULL
)
332 /* Create an output file for this member. */
333 char *output_name
= cat (dir
, "/", bfd_get_filename(this_element
));
334 bfd
*output_bfd
= bfd_openw (output_name
, output_target
);
336 if (output_bfd
== (bfd
*) NULL
)
338 nonfatal (output_name
);
340 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
342 nonfatal (bfd_get_filename (obfd
));
345 if (bfd_check_format (this_element
, bfd_object
) == true)
347 copy_object (this_element
, output_bfd
);
350 bfd_close (output_bfd
);
351 /* Open the newly output file and attatch to our list. */
352 output_bfd
= bfd_openr (output_name
, output_target
);
354 /* Mark it for deletion. */
356 ptr
= &output_bfd
->next
;
357 this_element
->next
= bfd_openr_next_archived_file (ibfd
, this_element
);
358 this_element
= this_element
->next
;
362 if (!bfd_close (obfd
))
364 nonfatal (bfd_get_filename (obfd
));
367 /* Delete all the files that we opened.
368 Construct their names again, unfortunately, but
369 we're about to exit anyway. */
370 for (this_element
= ibfd
->archive_head
;
371 this_element
!= (bfd
*) NULL
;
372 this_element
= this_element
->next
)
374 unlink (cat (dir
, "/", bfd_get_filename (this_element
)));
377 if (!bfd_close (ibfd
))
379 nonfatal (bfd_get_filename (ibfd
));
383 /* The top-level control. */
386 copy_file (input_filename
, output_filename
, input_target
, output_target
)
387 char *input_filename
;
388 char *output_filename
;
394 /* To allow us to do "strip *" without dying on the first
395 non-object file, failures are nonfatal. */
397 ibfd
= bfd_openr (input_filename
, input_target
);
400 nonfatal (input_filename
);
403 if (bfd_check_format (ibfd
, bfd_object
))
405 bfd
*obfd
= bfd_openw (output_filename
, output_target
);
408 nonfatal (output_filename
);
411 copy_object (ibfd
, obfd
);
413 if (!bfd_close (obfd
))
415 nonfatal (output_filename
);
418 if (!bfd_close (ibfd
))
420 nonfatal (input_filename
);
423 else if (bfd_check_format (ibfd
, bfd_archive
))
425 bfd
*obfd
= bfd_openw (output_filename
, output_target
);
428 nonfatal (output_filename
);
430 copy_archive (ibfd
, obfd
, output_target
);
434 /* Get the right error message. */
435 bfd_check_format (ibfd
, bfd_object
);
436 nonfatal (input_filename
);
440 /* Create a section in OBFD with the same name and attributes
441 as ISECTION in IBFD. */
444 setup_section (ibfd
, isection
, obfd
)
452 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
453 && (strip_symbols
== strip_debug
454 || strip_symbols
== strip_all
455 || discard_locals
== locals_all
))
458 osection
= bfd_get_section_by_name (obfd
, bfd_section_name (ibfd
, isection
));
459 if (osection
== NULL
)
461 osection
= bfd_make_section (obfd
, bfd_section_name (ibfd
, isection
));
462 if (osection
== NULL
)
469 if (!bfd_set_section_size (obfd
,
471 bfd_section_size (ibfd
, isection
)))
477 if (bfd_set_section_vma (obfd
,
479 bfd_section_vma (ibfd
, isection
))
486 if (bfd_set_section_alignment (obfd
,
488 bfd_section_alignment (ibfd
, isection
))
495 if (!bfd_set_section_flags (obfd
, osection
,
496 bfd_get_section_flags (ibfd
, isection
)))
506 fprintf (stderr
, "%s: %s: section `%s': error in %s: %s\n",
508 bfd_get_filename (ibfd
), bfd_section_name (ibfd
, isection
),
509 err
, bfd_errmsg (bfd_error
));
513 /* Copy the data of input section ISECTION of IBFD
514 to an output section with the same name in OBFD.
515 If stripping then don't copy any relocation info. */
518 copy_section (ibfd
, isection
, obfd
)
528 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
529 && (strip_symbols
== strip_debug
530 || strip_symbols
== strip_all
531 || discard_locals
== locals_all
))
536 osection
= bfd_get_section_by_name (obfd
,
537 bfd_section_name (ibfd
, isection
));
539 size
= bfd_get_section_size_before_reloc (isection
);
544 if (strip_symbols
== strip_all
545 || bfd_get_reloc_upper_bound (ibfd
, isection
) == 0)
547 bfd_set_reloc (obfd
, osection
, (arelent
**) NULL
, 0);
551 relpp
= (arelent
**) xmalloc (bfd_get_reloc_upper_bound (ibfd
, isection
));
552 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, isympp
);
553 bfd_set_reloc (obfd
, osection
, relpp
, relcount
);
556 isection
->_cooked_size
= isection
->_raw_size
;
557 isection
->reloc_done
= true;
559 if (bfd_get_section_flags (ibfd
, isection
) & SEC_HAS_CONTENTS
)
561 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
563 if (!bfd_get_section_contents (ibfd
, isection
, memhunk
, (file_ptr
) 0,
566 nonfatal (bfd_get_filename (ibfd
));
570 filter_bytes (memhunk
, &size
);
572 if (!bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
575 nonfatal (bfd_get_filename (obfd
));
581 /* All the symbols have been read in and point to their owning input section.
582 They have been relocated so that they are all relative to the base of
583 their owning section. On the way out, all the symbols will be relocated to
584 their new location in the output file, through some complex sums. */
587 mangle_section (ibfd
, p
, obfd
)
592 p
->output_section
= bfd_get_section_by_name (obfd
, p
->name
);
593 p
->output_offset
= 0;
596 /* The number of bytes to copy at once. */
597 #define COPY_BUF 8192
599 /* Copy file FROM to file TO, performing no translations.
600 Return 0 if ok, -1 if error. */
603 simple_copy (from
, to
)
606 int fromfd
, tofd
, nread
;
609 fromfd
= open (from
, O_RDONLY
);
612 tofd
= open (to
, O_WRONLY
| O_CREAT
| O_TRUNC
);
618 while ((nread
= read (fromfd
, buf
, sizeof buf
)) > 0)
620 if (write (tofd
, buf
, nread
) != nread
)
636 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
643 /* Rename FROM to TO, copying if TO is a link.
644 Assumes that TO already exists, because FROM is a temp file.
645 Return 0 if ok, -1 if error. */
648 smart_rename (from
, to
)
657 /* Use rename only if TO is not a symbolic link and has
658 only one hard link. */
659 if (!S_ISLNK (s
.st_mode
) && s
.st_nlink
== 1)
661 ret
= rename (from
, to
);
664 /* Try to preserve the permission bits and ownership of TO. */
665 chmod (to
, s
.st_mode
& 07777);
666 chown (to
, s
.st_uid
, s
.st_gid
);
671 ret
= simple_copy (from
, to
);
679 strip_main (argc
, argv
)
683 char *input_target
= NULL
, *output_target
= NULL
;
684 boolean show_version
= false;
687 while ((c
= getopt_long (argc
, argv
, "I:O:F:sSgxXVv",
688 strip_options
, (int *) 0)) != EOF
)
693 input_target
= optarg
;
695 output_target
= optarg
;
698 input_target
= output_target
= optarg
;
701 strip_symbols
= strip_all
;
705 strip_symbols
= strip_debug
;
708 discard_locals
= locals_all
;
711 discard_locals
= locals_start_L
;
720 break; /* we've been given a long option */
722 strip_usage (stdout
, 0);
724 strip_usage (stderr
, 1);
730 printf ("GNU %s version %s\n", program_name
, program_version
);
734 /* Default is to strip all symbols. */
735 if (strip_symbols
== strip_undef
&& discard_locals
== locals_undef
)
736 strip_symbols
= strip_all
;
738 if (output_target
== (char *) NULL
)
739 output_target
= input_target
;
743 strip_usage (stderr
, 1);
745 for (; i
< argc
; i
++)
747 int hold_status
= status
;
749 char *tmpname
= make_tempname (argv
[i
]);
751 copy_file (argv
[i
], tmpname
, input_target
, output_target
);
754 smart_rename (tmpname
, argv
[i
]);
755 status
= hold_status
;
766 copy_main (argc
, argv
)
770 char *input_filename
, *output_filename
;
771 char *input_target
= NULL
, *output_target
= NULL
;
772 boolean show_version
= false;
775 while ((c
= getopt_long (argc
, argv
, "b:i:I:s:O:d:F:SgxXVv",
776 copy_options
, (int *) 0)) != EOF
)
781 copy_byte
= atoi(optarg
);
784 fprintf (stderr
, "%s: byte number must be non-negative\n",
790 interleave
= atoi(optarg
);
793 fprintf(stderr
, "%s: interleave must be positive\n",
799 case 's': /* "source" - 'I' is preferred */
800 input_target
= optarg
;
802 case 'd': /* "destination" - 'O' is preferred */
803 output_target
= optarg
;
806 input_target
= output_target
= optarg
;
809 strip_symbols
= strip_all
;
812 strip_symbols
= strip_debug
;
815 discard_locals
= locals_all
;
818 discard_locals
= locals_start_L
;
827 break; /* we've been given a long option */
829 copy_usage (stdout
, 0);
831 copy_usage (stderr
, 1);
837 printf ("GNU %s version %s\n", program_name
, program_version
);
841 if (copy_byte
>= interleave
)
843 fprintf (stderr
, "%s: byte number must be less than interleave\n",
848 if (optind
== argc
|| optind
+ 2 < argc
)
849 copy_usage (stderr
, 1);
851 input_filename
= argv
[optind
];
852 if (optind
+ 1 < argc
)
853 output_filename
= argv
[optind
+ 1];
855 /* Default is to strip no symbols. */
856 if (strip_symbols
== strip_undef
&& discard_locals
== locals_undef
)
857 strip_symbols
= strip_none
;
859 if (output_target
== (char *) NULL
)
860 output_target
= input_target
;
862 /* If there is no destination file then create a temp and rename
863 the result into the input. */
865 if (output_filename
== (char *) NULL
)
867 char *tmpname
= make_tempname (input_filename
);
868 copy_file (input_filename
, tmpname
, input_target
, output_target
);
870 smart_rename (tmpname
, input_filename
);
876 copy_file (input_filename
, output_filename
, input_target
, output_target
);
887 program_name
= argv
[0];
888 strip_symbols
= strip_undef
;
889 discard_locals
= locals_undef
;
895 int i
= strlen (program_name
);
896 is_strip
= (i
>= 5 && strcmp (program_name
+ i
- 5, "strip"));
900 strip_main (argc
, argv
);
902 copy_main (argc
, argv
);