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
;
395 /* To allow us to do "strip *" without dying on the first
396 non-object file, failures are nonfatal. */
398 ibfd
= bfd_openr (input_filename
, input_target
);
401 nonfatal (input_filename
);
404 if (bfd_check_format (ibfd
, bfd_archive
))
406 bfd
*obfd
= bfd_openw (output_filename
, output_target
);
409 nonfatal (output_filename
);
411 copy_archive (ibfd
, obfd
, output_target
);
413 else if (bfd_check_format_matches (ibfd
, bfd_object
, &matching
))
415 bfd
*obfd
= bfd_openw (output_filename
, output_target
);
418 nonfatal (output_filename
);
421 copy_object (ibfd
, obfd
);
423 if (!bfd_close (obfd
))
425 nonfatal (output_filename
);
428 if (!bfd_close (ibfd
))
430 nonfatal (input_filename
);
435 bfd_nonfatal (input_filename
);
436 if (bfd_error
== file_ambiguously_recognized
)
438 list_matching_formats (matching
);
445 /* Create a section in OBFD with the same name and attributes
446 as ISECTION in IBFD. */
449 setup_section (ibfd
, isection
, obfd
)
457 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
458 && (strip_symbols
== strip_debug
459 || strip_symbols
== strip_all
460 || discard_locals
== locals_all
))
463 osection
= bfd_get_section_by_name (obfd
, bfd_section_name (ibfd
, isection
));
464 if (osection
== NULL
)
466 osection
= bfd_make_section (obfd
, bfd_section_name (ibfd
, isection
));
467 if (osection
== NULL
)
474 if (!bfd_set_section_size (obfd
,
476 bfd_section_size (ibfd
, isection
)))
482 if (bfd_set_section_vma (obfd
,
484 bfd_section_vma (ibfd
, isection
))
491 if (bfd_set_section_alignment (obfd
,
493 bfd_section_alignment (ibfd
, isection
))
500 if (!bfd_set_section_flags (obfd
, osection
,
501 bfd_get_section_flags (ibfd
, isection
)))
511 fprintf (stderr
, "%s: %s: section `%s': error in %s: %s\n",
513 bfd_get_filename (ibfd
), bfd_section_name (ibfd
, isection
),
514 err
, bfd_errmsg (bfd_error
));
518 /* Copy the data of input section ISECTION of IBFD
519 to an output section with the same name in OBFD.
520 If stripping then don't copy any relocation info. */
523 copy_section (ibfd
, isection
, obfd
)
533 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
534 && (strip_symbols
== strip_debug
535 || strip_symbols
== strip_all
536 || discard_locals
== locals_all
))
541 osection
= bfd_get_section_by_name (obfd
,
542 bfd_section_name (ibfd
, isection
));
544 size
= bfd_get_section_size_before_reloc (isection
);
549 if (strip_symbols
== strip_all
550 || bfd_get_reloc_upper_bound (ibfd
, isection
) == 0)
552 bfd_set_reloc (obfd
, osection
, (arelent
**) NULL
, 0);
556 relpp
= (arelent
**) xmalloc (bfd_get_reloc_upper_bound (ibfd
, isection
));
557 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, isympp
);
558 bfd_set_reloc (obfd
, osection
, relpp
, relcount
);
561 isection
->_cooked_size
= isection
->_raw_size
;
562 isection
->reloc_done
= true;
564 if (bfd_get_section_flags (ibfd
, isection
) & SEC_HAS_CONTENTS
)
566 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
568 if (!bfd_get_section_contents (ibfd
, isection
, memhunk
, (file_ptr
) 0,
571 nonfatal (bfd_get_filename (ibfd
));
575 filter_bytes (memhunk
, &size
);
577 if (!bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
580 nonfatal (bfd_get_filename (obfd
));
586 /* All the symbols have been read in and point to their owning input section.
587 They have been relocated so that they are all relative to the base of
588 their owning section. On the way out, all the symbols will be relocated to
589 their new location in the output file, through some complex sums. */
592 mangle_section (ibfd
, p
, obfd
)
597 p
->output_section
= bfd_get_section_by_name (obfd
, p
->name
);
598 p
->output_offset
= 0;
601 /* The number of bytes to copy at once. */
602 #define COPY_BUF 8192
604 /* Copy file FROM to file TO, performing no translations.
605 Return 0 if ok, -1 if error. */
608 simple_copy (from
, to
)
611 int fromfd
, tofd
, nread
;
614 fromfd
= open (from
, O_RDONLY
);
617 tofd
= open (to
, O_WRONLY
| O_CREAT
| O_TRUNC
);
623 while ((nread
= read (fromfd
, buf
, sizeof buf
)) > 0)
625 if (write (tofd
, buf
, nread
) != nread
)
641 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
648 /* Rename FROM to TO, copying if TO is a link.
649 Assumes that TO already exists, because FROM is a temp file.
650 Return 0 if ok, -1 if error. */
653 smart_rename (from
, to
)
662 /* Use rename only if TO is not a symbolic link and has
663 only one hard link. */
664 if (!S_ISLNK (s
.st_mode
) && s
.st_nlink
== 1)
666 ret
= rename (from
, to
);
669 /* Try to preserve the permission bits and ownership of TO. */
670 chmod (to
, s
.st_mode
& 07777);
671 chown (to
, s
.st_uid
, s
.st_gid
);
676 ret
= simple_copy (from
, to
);
684 strip_main (argc
, argv
)
688 char *input_target
= NULL
, *output_target
= NULL
;
689 boolean show_version
= false;
692 while ((c
= getopt_long (argc
, argv
, "I:O:F:sSgxXVv",
693 strip_options
, (int *) 0)) != EOF
)
698 input_target
= optarg
;
700 output_target
= optarg
;
703 input_target
= output_target
= optarg
;
706 strip_symbols
= strip_all
;
710 strip_symbols
= strip_debug
;
713 discard_locals
= locals_all
;
716 discard_locals
= locals_start_L
;
725 break; /* we've been given a long option */
727 strip_usage (stdout
, 0);
729 strip_usage (stderr
, 1);
735 printf ("GNU %s version %s\n", program_name
, program_version
);
739 /* Default is to strip all symbols. */
740 if (strip_symbols
== strip_undef
&& discard_locals
== locals_undef
)
741 strip_symbols
= strip_all
;
743 if (output_target
== (char *) NULL
)
744 output_target
= input_target
;
748 strip_usage (stderr
, 1);
750 for (; i
< argc
; i
++)
752 int hold_status
= status
;
754 char *tmpname
= make_tempname (argv
[i
]);
756 copy_file (argv
[i
], tmpname
, input_target
, output_target
);
759 smart_rename (tmpname
, argv
[i
]);
760 status
= hold_status
;
771 copy_main (argc
, argv
)
775 char *input_filename
, *output_filename
;
776 char *input_target
= NULL
, *output_target
= NULL
;
777 boolean show_version
= false;
780 while ((c
= getopt_long (argc
, argv
, "b:i:I:s:O:d:F:SgxXVv",
781 copy_options
, (int *) 0)) != EOF
)
786 copy_byte
= atoi(optarg
);
789 fprintf (stderr
, "%s: byte number must be non-negative\n",
795 interleave
= atoi(optarg
);
798 fprintf(stderr
, "%s: interleave must be positive\n",
804 case 's': /* "source" - 'I' is preferred */
805 input_target
= optarg
;
807 case 'd': /* "destination" - 'O' is preferred */
808 output_target
= optarg
;
811 input_target
= output_target
= optarg
;
814 strip_symbols
= strip_all
;
817 strip_symbols
= strip_debug
;
820 discard_locals
= locals_all
;
823 discard_locals
= locals_start_L
;
832 break; /* we've been given a long option */
834 copy_usage (stdout
, 0);
836 copy_usage (stderr
, 1);
842 printf ("GNU %s version %s\n", program_name
, program_version
);
846 if (copy_byte
>= interleave
)
848 fprintf (stderr
, "%s: byte number must be less than interleave\n",
853 if (optind
== argc
|| optind
+ 2 < argc
)
854 copy_usage (stderr
, 1);
856 input_filename
= argv
[optind
];
857 if (optind
+ 1 < argc
)
858 output_filename
= argv
[optind
+ 1];
860 /* Default is to strip no symbols. */
861 if (strip_symbols
== strip_undef
&& discard_locals
== locals_undef
)
862 strip_symbols
= strip_none
;
864 if (output_target
== (char *) NULL
)
865 output_target
= input_target
;
867 /* If there is no destination file then create a temp and rename
868 the result into the input. */
870 if (output_filename
== (char *) NULL
)
872 char *tmpname
= make_tempname (input_filename
);
873 copy_file (input_filename
, tmpname
, input_target
, output_target
);
875 smart_rename (tmpname
, input_filename
);
881 copy_file (input_filename
, output_filename
, input_target
, output_target
);
892 program_name
= argv
[0];
893 strip_symbols
= strip_undef
;
894 discard_locals
= locals_undef
;
900 int i
= strlen (program_name
);
901 is_strip
= (i
>= 5 && strcmp (program_name
+ i
- 5, "strip"));
905 strip_main (argc
, argv
);
907 copy_main (argc
, argv
);