1 /* copy.c -- copy object file from input to output, optionally massaging it.
2 Copyright (C) 1991 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. */
24 char *input_target = NULL;
25 char *output_target = NULL;
26 char *input_filename = NULL;
27 char *output_filename = NULL;
30 static void setup_sections();
31 static void copy_sections();
33 static boolean verbose;
36 extern char *program_name;
37 extern char *xmalloc();
44 "Usage %s [-S][-s srcfmt] [-d dtfmt] [-b bothfmts] infile [outfile]\n",
50 /* Create a temp file in the same directory as supplied */
53 make_tempname(filename)
56 static char template[] = "stXXXXXX";
58 char * slash = strrchr( filename, '/' );
59 if (slash != (char *)NULL){
61 tmpname = xmalloc(strlen(filename) + sizeof(template) + 1 );
62 strcpy(tmpname, filename);
63 strcat(tmpname, "/" );
64 strcat(tmpname, template);
68 tmpname = xmalloc(sizeof(template));
69 strcpy(tmpname, template);
76 All the symbols have been read in and point to their owning input section.
77 They have been relocated to that they are all relative to the base of
78 their owning section. On the way out, all the symbols will be relocated to
79 their new location in the output file, through some complex sums.
83 mangle_sections(ibfd, obfd)
87 asection *current = ibfd->sections;
88 for (; current != NULL; current = current->next) {
89 current->output_section = bfd_get_section_by_name(obfd, current->name);
90 current->output_offset = 0;
96 copy_object(ibfd, obfd)
101 unsigned int symcount;
104 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
105 bfd_fatal(output_filename);
109 printf("copy from %s(%s) to %s(%s)\n",
110 ibfd->filename, ibfd->xvec->name,
111 obfd->filename, obfd->xvec->name);
113 if ((bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false)
115 (bfd_set_file_flags(obfd, (bfd_get_file_flags(ibfd) &
116 (HAS_LINENO | HAS_DEBUG |
117 HAS_RELOC | HAS_SYMS | D_PAGED |
118 HAS_LOCALS))) == false)) {
119 bfd_fatal(bfd_get_filename(ibfd));
122 /* Copy architecture of input file to output file */
123 if (!bfd_set_arch_mach(obfd, bfd_get_arch(ibfd),
124 bfd_get_mach(ibfd))) {
125 fprintf(stderr, "Output file cannot represent architecture %s\n",
126 bfd_printable_arch_mach(bfd_get_arch(ibfd),
127 bfd_get_mach(ibfd)));
129 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
131 bfd_fatal(ibfd->filename);
134 sympp = (asymbol **) xmalloc(get_symtab_upper_bound(ibfd));
135 symcount = bfd_canonicalize_symtab(ibfd, sympp);
137 bfd_set_symtab(obfd, sympp, strip == true ? 0 : symcount);
140 bfd mandates that all output sections be created and sizes set before
141 any output is done. Thus, we traverse all sections twice.
143 bfd_map_over_sections(ibfd, setup_sections, (void *) obfd);
144 bfd_map_over_sections(ibfd, copy_sections, (void *) obfd);
145 mangle_sections(ibfd, obfd);
154 int size = strlen(a) + strlen(b) + strlen(c);
155 char *r = xmalloc(size+1);
163 copy_archive(ibfd, obfd)
167 bfd **ptr = &obfd->archive_head;
169 /* Read each archive element in turn from the input, copy the
170 contents to a temp file, and keep the temp file handle */
171 char *dir = cat("./#",make_tempname(""),"cd");
173 /* Make a temp directory to hold the contents */
175 obfd->has_armap = ibfd->has_armap;
176 this_element = bfd_openr_next_archived_file(ibfd, NULL);
177 ibfd->archive_head = this_element;
178 while (this_element != (bfd *)NULL) {
180 /* Create an output file for this member */
181 char *output_name = cat(dir, "/",this_element->filename);
182 bfd *output_bfd = bfd_openw(output_name, output_target);
184 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
185 bfd_fatal(output_filename);
187 if (output_bfd == (bfd *)NULL) {
188 bfd_fatal(output_name);
190 if (bfd_check_format(this_element, bfd_object) == true) {
191 copy_object(this_element, output_bfd);
194 bfd_close(output_bfd);
195 /* Now open the newly output file and attatch to our list */
196 output_bfd = bfd_openr(output_name, output_target);
197 /* Mark it for deletion */
201 ptr = &output_bfd->next;
202 this_element->next = bfd_openr_next_archived_file(ibfd, this_element);
203 this_element = this_element->next;
208 if (!bfd_close(obfd))
209 bfd_fatal(output_filename);
211 /* Now delete all the files that we opened.
212 Construct their names again, unfortunately, but so what;
213 we're about to exit anyway. */
214 for (this_element = ibfd->archive_head;
215 this_element != (bfd *)NULL;
216 this_element = this_element->next)
218 unlink(cat(dir,"/",this_element->filename));
221 if (!bfd_close(ibfd))
222 bfd_fatal(input_filename);
228 copy_file(input_filename, output_filename)
229 char *input_filename;
230 char *output_filename;
234 ibfd = bfd_openr(input_filename, input_target);
236 bfd_fatal(input_filename);
238 if (bfd_check_format(ibfd, bfd_object)) {
239 bfd * obfd = bfd_openw(output_filename, output_target);
241 bfd_fatal(output_filename);
243 copy_object(ibfd, obfd);
245 if (!bfd_close(obfd))
246 bfd_fatal(output_filename);
248 if (!bfd_close(ibfd))
249 bfd_fatal(input_filename);
251 else if (bfd_check_format(ibfd, bfd_archive)) {
252 bfd * obfd = bfd_openw(output_filename, output_target);
254 bfd_fatal(output_filename);
255 copy_archive(ibfd, obfd);
261 /** Actually do the work */
263 setup_sections(ibfd, isection, obfd)
270 osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
271 if (osection == NULL) {
276 if (!bfd_set_section_size(obfd,
278 bfd_section_size(ibfd, isection))) {
283 if (bfd_set_section_vma(obfd,
285 bfd_section_vma(ibfd, isection))
291 if (bfd_set_section_alignment(obfd,
293 bfd_section_alignment(ibfd, isection))
299 if (!bfd_set_section_flags(obfd, osection,
300 bfd_get_section_flags(ibfd, isection))) {
309 fprintf(stderr, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
311 bfd_get_filename(ibfd), bfd_section_name(ibfd, isection),
312 err, bfd_errmsg(bfd_error));
314 } /* setup_sections() */
317 Copy all the section related data from an input section
320 If stripping then don't copy any relocation info
323 copy_sections(ibfd, isection, obfd)
333 osection = bfd_get_section_by_name(obfd,
334 bfd_section_name(ibfd, isection));
336 size = isection->size;
341 if (strip == true || get_reloc_upper_bound(ibfd, isection) == 0)
343 bfd_set_reloc(obfd, osection, (arelent **)NULL, 0);
347 relpp = (arelent **) xmalloc(get_reloc_upper_bound(ibfd, isection));
348 relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
349 bfd_set_reloc(obfd, osection, relpp, relcount);
353 if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS)
355 PTR memhunk = (PTR) xmalloc((unsigned)size);
357 if (!bfd_get_section_contents(ibfd, isection, memhunk, (file_ptr) 0, size))
358 bfd_fatal(bfd_get_filename(ibfd));
360 if (!bfd_set_section_contents(obfd, osection, memhunk, (file_ptr)0, size))
361 bfd_fatal(bfd_get_filename(obfd));
374 program_name = argv[0];
378 if (strcmp(program_name,"strip") == 0) {
382 for (i = 1; i < argc; i++)
384 if (argv[i][0] == '-') {
385 switch (argv[i][1]) {
391 input_target = output_target = argv[i];
398 input_target = argv[i];
402 output_target = argv[i];
409 if (input_filename) {
410 output_filename = argv[i];
413 input_filename = argv[i];
418 if (input_filename == (char *) NULL)
421 if (output_target == (char *) NULL)
422 output_target = input_target;
424 /* If there is no destination file then create a temp and rename
425 the result into the input */
427 if (output_filename == (char *)NULL) {
428 char * tmpname = make_tempname(input_filename);
429 copy_file(input_filename, tmpname);
430 output_filename = input_filename;
431 rename(tmpname, input_filename);
434 copy_file(input_filename, output_filename);