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. */
25 char *input_target
= NULL
;
26 char *output_target
= NULL
;
27 char *input_filename
= NULL
;
28 char *output_filename
= NULL
;
31 static void setup_sections();
32 static void copy_sections();
33 static boolean verbose
;
35 /* This flag distinguishes between strip and copy:
36 1 means this is 'strip'; 0 means this is 'copy'.
37 -1 means if we should use argv[0] to decide. */
41 extern char *program_name
;
42 extern char *program_version
;
50 "Usage %s [-S][-s srcfmt] [-d dtfmt] [-b bothfmts] infile [outfile] [-vV]\n",
59 fprintf(stderr
, "Usage %s [-vV] filename ...\n", program_name
);
64 /* Create a temp file in the same directory as supplied */
67 make_tempname(filename
)
70 static char template[] = "stXXXXXX";
72 char * slash
= strrchr( filename
, '/' );
73 if (slash
!= (char *)NULL
){
75 tmpname
= xmalloc(strlen(filename
) + sizeof(template) + 1 );
76 strcpy(tmpname
, filename
);
77 strcat(tmpname
, "/" );
78 strcat(tmpname
, template);
82 tmpname
= xmalloc(sizeof(template));
83 strcpy(tmpname
, template);
90 All the symbols have been read in and point to their owning input section.
91 They have been relocated to that they are all relative to the base of
92 their owning section. On the way out, all the symbols will be relocated to
93 their new location in the output file, through some complex sums.
97 mangle_sections(ibfd
, obfd
)
101 asection
*current
= ibfd
->sections
;
102 for (; current
!= NULL
; current
= current
->next
) {
103 current
->output_section
= bfd_get_section_by_name(obfd
, current
->name
);
104 current
->output_offset
= 0;
110 copy_object(ibfd
, obfd
)
115 unsigned int symcount
;
118 if (!bfd_set_format(obfd
, bfd_get_format(ibfd
)))
119 bfd_fatal(output_filename
);
123 printf("copy from %s(%s) to %s(%s)\n",
124 ibfd
->filename
, ibfd
->xvec
->name
,
125 obfd
->filename
, obfd
->xvec
->name
);
127 if ((bfd_set_start_address(obfd
, bfd_get_start_address(ibfd
)) == false)
129 (bfd_set_file_flags(obfd
, (bfd_get_file_flags(ibfd
) &
130 (HAS_LINENO
| HAS_DEBUG
|
131 HAS_RELOC
| HAS_SYMS
| D_PAGED
|
132 HAS_LOCALS
))) == false)) {
133 bfd_fatal(bfd_get_filename(ibfd
));
136 /* Copy architecture of input file to output file */
137 if (!bfd_set_arch_mach(obfd
, bfd_get_arch(ibfd
),
138 bfd_get_mach(ibfd
))) {
139 fprintf(stderr
, "Output file cannot represent architecture %s\n",
140 bfd_printable_arch_mach(bfd_get_arch(ibfd
),
141 bfd_get_mach(ibfd
)));
143 if (!bfd_set_format(obfd
, bfd_get_format(ibfd
)))
145 bfd_fatal(ibfd
->filename
);
148 sympp
= (asymbol
**) xmalloc(get_symtab_upper_bound(ibfd
));
149 symcount
= bfd_canonicalize_symtab(ibfd
, sympp
);
151 bfd_set_symtab(obfd
, sympp
, is_strip
? 0 : symcount
);
154 bfd mandates that all output sections be created and sizes set before
155 any output is done. Thus, we traverse all sections twice.
157 bfd_map_over_sections(ibfd
, setup_sections
, (void *) obfd
);
158 bfd_map_over_sections(ibfd
, copy_sections
, (void *) obfd
);
159 mangle_sections(ibfd
, obfd
);
168 int size
= strlen(a
) + strlen(b
) + strlen(c
);
169 char *r
= xmalloc(size
+1);
177 copy_archive(ibfd
, obfd
)
181 bfd
**ptr
= &obfd
->archive_head
;
183 /* Read each archive element in turn from the input, copy the
184 contents to a temp file, and keep the temp file handle */
185 char *dir
= cat("./#",make_tempname(""),"cd");
187 /* Make a temp directory to hold the contents */
189 obfd
->has_armap
= ibfd
->has_armap
;
190 this_element
= bfd_openr_next_archived_file(ibfd
, NULL
);
191 ibfd
->archive_head
= this_element
;
192 while (this_element
!= (bfd
*)NULL
) {
194 /* Create an output file for this member */
195 char *output_name
= cat(dir
, "/",this_element
->filename
);
196 bfd
*output_bfd
= bfd_openw(output_name
, output_target
);
198 if (!bfd_set_format(obfd
, bfd_get_format(ibfd
)))
199 bfd_fatal(output_filename
);
201 if (output_bfd
== (bfd
*)NULL
) {
202 bfd_fatal(output_name
);
204 if (bfd_check_format(this_element
, bfd_object
) == true) {
205 copy_object(this_element
, output_bfd
);
208 bfd_close(output_bfd
);
209 /* Now open the newly output file and attatch to our list */
210 output_bfd
= bfd_openr(output_name
, output_target
);
211 /* Mark it for deletion */
215 ptr
= &output_bfd
->next
;
216 this_element
->next
= bfd_openr_next_archived_file(ibfd
, this_element
);
217 this_element
= this_element
->next
;
222 if (!bfd_close(obfd
))
223 bfd_fatal(output_filename
);
225 /* Now delete all the files that we opened.
226 Construct their names again, unfortunately, but so what;
227 we're about to exit anyway. */
228 for (this_element
= ibfd
->archive_head
;
229 this_element
!= (bfd
*)NULL
;
230 this_element
= this_element
->next
)
232 unlink(cat(dir
,"/",this_element
->filename
));
235 if (!bfd_close(ibfd
))
236 bfd_fatal(input_filename
);
242 copy_file(input_filename
, output_filename
)
243 char *input_filename
;
244 char *output_filename
;
248 ibfd
= bfd_openr(input_filename
, input_target
);
250 bfd_fatal(input_filename
);
252 if (bfd_check_format(ibfd
, bfd_object
)) {
253 bfd
* obfd
= bfd_openw(output_filename
, output_target
);
255 bfd_fatal(output_filename
);
257 copy_object(ibfd
, obfd
);
259 if (ibfd
->flags
& EXEC_P
)
260 obfd
->flags
|= EXEC_P
;
261 if (!bfd_close(obfd
))
262 bfd_fatal(output_filename
);
264 if (!bfd_close(ibfd
))
265 bfd_fatal(input_filename
);
267 else if (bfd_check_format(ibfd
, bfd_archive
)) {
268 bfd
* obfd
= bfd_openw(output_filename
, output_target
);
270 bfd_fatal(output_filename
);
271 copy_archive(ibfd
, obfd
);
277 /** Actually do the work */
279 setup_sections(ibfd
, isection
, obfd
)
287 osection
= bfd_get_section_by_name(obfd
, bfd_section_name(ibfd
, isection
));
288 if (osection
== NULL
) {
289 osection
= bfd_make_section(obfd
, bfd_section_name(ibfd
, isection
));
290 if (osection
== NULL
) {
296 if (!bfd_set_section_size(obfd
,
298 bfd_section_size(ibfd
, isection
))) {
303 if (bfd_set_section_vma(obfd
,
305 bfd_section_vma(ibfd
, isection
))
311 if (bfd_set_section_alignment(obfd
,
313 bfd_section_alignment(ibfd
, isection
))
319 if (!bfd_set_section_flags(obfd
, osection
,
320 bfd_get_section_flags(ibfd
, isection
))) {
329 fprintf(stderr
, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
331 bfd_get_filename(ibfd
), bfd_section_name(ibfd
, isection
),
332 err
, bfd_errmsg(bfd_error
));
334 } /* setup_sections() */
337 Copy all the section related data from an input section
340 If stripping then don't copy any relocation info
343 copy_sections(ibfd
, isection
, obfd
)
353 osection
= bfd_get_section_by_name(obfd
,
354 bfd_section_name(ibfd
, isection
));
356 size
= bfd_get_section_size_before_reloc(isection
);
361 if (is_strip
|| bfd_get_reloc_upper_bound(ibfd
, isection
) == 0)
363 bfd_set_reloc(obfd
, osection
, (arelent
**)NULL
, 0);
367 relpp
= (arelent
**) xmalloc(bfd_get_reloc_upper_bound(ibfd
, isection
));
368 relcount
= bfd_canonicalize_reloc(ibfd
, isection
, relpp
, sympp
);
369 bfd_set_reloc(obfd
, osection
, relpp
, relcount
);
372 isection
->_cooked_size
= isection
->_raw_size
;
373 isection
->reloc_done
=true;
376 if (bfd_get_section_flags(ibfd
, isection
) & SEC_HAS_CONTENTS
)
378 PTR memhunk
= (PTR
) xmalloc((unsigned)size
);
380 if (!bfd_get_section_contents(ibfd
, isection
, memhunk
, (file_ptr
) 0, size
))
381 bfd_fatal(bfd_get_filename(ibfd
));
383 if (!bfd_set_section_contents(obfd
, osection
, memhunk
, (file_ptr
)0, size
))
384 bfd_fatal(bfd_get_filename(obfd
));
396 int show_version
= 0;
397 program_name
= argv
[0];
402 i
= strlen (program_name
);
403 is_strip
= (i
>= 5 && strcmp(program_name
+i
-5,"strip"));
408 for (i
= 1; i
< argc
; i
++)
410 if (argv
[i
][0] != '-')
412 if (argv
[i
][1] == '-') {
416 switch (argv
[i
][1]) {
425 /* undocumented for now */
428 output_target
= argv
[i
];
435 printf ("%s version %s\n", program_name
, program_version
);
436 for ( ; i
< argc
; i
++) {
437 char *tmpname
= make_tempname(argv
[i
]);
438 copy_file(argv
[i
], tmpname
);
439 rename(tmpname
, argv
[i
]);
444 for (i
= 1; i
< argc
; i
++)
446 if (argv
[i
][0] == '-') {
447 switch (argv
[i
][1]) {
457 input_target
= output_target
= argv
[i
];
464 input_target
= argv
[i
];
468 output_target
= argv
[i
];
475 if (input_filename
) {
476 output_filename
= argv
[i
];
479 input_filename
= argv
[i
];
485 printf ("%s version %s\n", program_name
, program_version
);
487 if (input_filename
== (char *) NULL
)
490 if (output_target
== (char *) NULL
)
491 output_target
= input_target
;
493 /* If there is no destination file then create a temp and rename
494 the result into the input */
496 if (output_filename
== (char *)NULL
) {
497 char * tmpname
= make_tempname(input_filename
);
498 copy_file(input_filename
, tmpname
);
499 output_filename
= input_filename
;
500 rename(tmpname
, input_filename
);
503 copy_file(input_filename
, output_filename
);
This page took 0.039578 seconds and 4 git commands to generate.