1 /*** copy.c -- copy object file from input to output, optionally massaging it */
6 char *input_target = NULL;
7 char *output_target = NULL;
8 char *input_filename = NULL;
9 char *output_filename = NULL;
12 static void setup_sections();
13 static void copy_sections();
15 static boolean verbose;
18 extern char *program_name;
19 extern char *xmalloc();
26 "Usage %s [-S][-s srcfmt] [-d dtfmt] [-b bothfmts] infile [outfile]\n",
32 /* Create a temp file in the same directory as supplied */
35 make_tempname(filename)
38 static char template[] = "stXXXXXX";
40 char * slash = strrchr( filename, '/' );
41 if (slash != (char *)NULL){
43 tmpname = xmalloc(strlen(filename) + sizeof(template) + 1 );
44 strcpy(tmpname, filename);
45 strcat(tmpname, "/" );
46 strcat(tmpname, template);
50 tmpname = xmalloc(sizeof(template));
51 strcpy(tmpname, template);
58 All the symbols have been read in and point to their owning input section.
59 They have been relocated to that they are all relative to the base of
60 their owning section. On the way out, all the symbols will be relocated to
61 their new location in the output file, through some complex sums.
65 mangle_sections(ibfd, obfd)
69 asection *current = ibfd->sections;
70 for (; current != NULL; current = current->next) {
71 current->output_section = bfd_get_section_by_name(obfd, current->name);
72 current->output_offset = 0;
78 copy_object(ibfd, obfd)
83 unsigned int symcount;
86 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
87 bfd_fatal(output_filename);
91 printf("copy from %s(%s) to %s(%s)\n",
92 ibfd->filename, ibfd->xvec->name,
93 obfd->filename, obfd->xvec->name);
95 if ((bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false) ||
96 (bfd_set_file_flags(obfd, (bfd_get_file_flags(ibfd) &
97 ~(HAS_LINENO | HAS_DEBUG | HAS_SYMS | D_PAGED |
98 HAS_LOCALS))) == false) ||
99 bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false)
100 bfd_fatal(bfd_get_filename(ibfd));
102 /* Copy architecture of input file to output file */
103 if (!bfd_set_arch_mach(obfd, bfd_get_architecture(ibfd),
104 bfd_get_machine(ibfd))) {
105 fprintf(stderr, "Output file cannot represent architecture %s\n",
106 bfd_printable_arch_mach(bfd_get_architecture(ibfd),
107 bfd_get_machine(ibfd)));
109 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
111 bfd_fatal(ibfd->filename);
114 sympp = (asymbol **) xmalloc(get_symtab_upper_bound(ibfd));
115 symcount = bfd_canonicalize_symtab(ibfd, sympp);
117 bfd_set_symtab(obfd, sympp, strip == true ? 0 : symcount);
120 bfd mandates that all output sections be created and sizes set before
121 any output is done. Thus, we traverse all sections twice.
123 bfd_map_over_sections(ibfd, setup_sections, (void *) obfd);
124 bfd_map_over_sections(ibfd, copy_sections, (void *) obfd);
125 mangle_sections(ibfd, obfd);
134 int size = strlen(a) + strlen(b) + strlen(c);
135 char *r = xmalloc(size+1);
143 copy_archive(ibfd, obfd)
147 bfd **ptr =&( obfd->archive_head);
149 /* Read each archive element in turn from the input, copy the
150 contents to a temp file, and keep the temp file handle */
151 char *dir = cat("./",make_tempname(this_element->filename),"copy-dir");
153 /* Make a temp directory to hold the contents */
155 obfd->has_armap = ibfd->has_armap;
156 this_element = bfd_openr_next_archived_file(ibfd, NULL);
157 while (this_element != (bfd *)NULL) {
159 /* Create an output file for this member */
160 char *output_name = cat(dir, "/",this_element->filename);
161 bfd *output_bfd = bfd_openw(output_name, output_target);
163 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
164 bfd_fatal(output_filename);
166 if (output_bfd == (bfd *)NULL) {
167 bfd_fatal(output_name);
169 if (bfd_check_format(this_element, bfd_object) == true) {
170 copy_object(this_element, output_bfd);
173 bfd_close(output_bfd);
174 /* Now open the newly output file and attatch to our list */
175 output_bfd = bfd_openr(output_name, output_target);
176 /* Mark it for deletion */
180 ptr =&( output_bfd->next);
181 this_element = bfd_openr_next_archived_file(ibfd, this_element);
186 if (!bfd_close(obfd))
187 bfd_fatal(output_filename);
189 /* Now delete all the files that we opened
190 We can't use the names in the obfd list since they may have been
191 trampled by the archive output code
193 for (this_element = ibfd->archive_head;
194 this_element != (bfd *)NULL;
195 this_element = this_element->next)
197 unlink(cat(dir,"/",this_element->filename));
200 if (!bfd_close(ibfd))
201 bfd_fatal(input_filename);
207 copy_file(input_filename, output_filename)
208 char *input_filename;
209 char *output_filename;
213 ibfd = bfd_openr(input_filename, input_target);
215 bfd_fatal(input_filename);
217 if (bfd_check_format(ibfd, bfd_object)) {
218 bfd * obfd = bfd_openw(output_filename, output_target);
220 bfd_fatal(output_filename);
222 copy_object(ibfd, obfd);
224 if (!bfd_close(obfd))
225 bfd_fatal(output_filename);
227 if (!bfd_close(ibfd))
228 bfd_fatal(input_filename);
230 else if (bfd_check_format(ibfd, bfd_archive)) {
231 bfd * obfd = bfd_openw(output_filename, output_target);
233 bfd_fatal(output_filename);
234 copy_archive(ibfd, obfd);
240 /** Actually do the work */
242 setup_sections(ibfd, isection, obfd)
249 osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
250 if (osection == NULL) {
255 if (!bfd_set_section_size(obfd,
257 bfd_section_size(ibfd, isection))) {
262 if (bfd_set_section_vma(obfd,
264 bfd_section_vma(ibfd, isection))
270 if (bfd_set_section_alignment(obfd,
272 bfd_section_alignment(ibfd, isection))
278 if (!bfd_set_section_flags(obfd, osection,
279 bfd_get_section_flags(ibfd, isection))) {
288 fprintf(stderr, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
290 bfd_get_filename(ibfd), bfd_section_name(ibfd, isection),
291 err, bfd_errmsg(bfd_error));
293 } /* setup_sections() */
296 Copy all the section related data from an input section
299 If stripping then don't copy any relocation info
302 copy_sections(ibfd, isection, obfd)
312 osection = bfd_get_section_by_name(obfd,
313 bfd_section_name(ibfd, isection));
315 size = bfd_section_size(ibfd, isection);
320 if (strip == true || get_reloc_upper_bound(ibfd, isection) == 0)
322 bfd_set_reloc(obfd, osection, (arelent **)NULL, 0);
326 relpp = (arelent **) xmalloc(get_reloc_upper_bound(ibfd, isection));
327 relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
328 bfd_set_reloc(obfd, osection, relpp, relcount);
332 if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS)
334 unsigned char *memhunk = (unsigned char *) xmalloc(size);
336 if (!bfd_get_section_contents(ibfd, isection, memhunk, 0, size))
337 bfd_fatal(bfd_get_filename(ibfd));
339 if (!bfd_set_section_contents(obfd, osection, memhunk, 0, size))
340 bfd_fatal(bfd_get_filename(obfd));
353 program_name = argv[0];
355 if (strcmp(program_name,"strip") == 0) {
359 for (i = 1; i < argc; i++)
361 if (argv[i][0] == '-') {
362 switch (argv[i][1]) {
368 input_target = output_target = argv[i];
375 input_target = argv[i];
379 output_target = argv[i];
386 if (input_filename) {
387 output_filename = argv[i];
390 input_filename = argv[i];
395 if (input_filename == (char *) NULL)
398 if (output_target == (char *) NULL)
399 output_target = input_target;
401 /* If there is no destination file then create a temp and rename
402 the result into the input */
404 if (output_filename == (char *)NULL) {
405 char * tmpname = make_tempname(input_filename);
406 copy_file(input_filename, tmpname);
407 output_filename = input_filename;
408 rename(tmpname, input_filename);
411 copy_file(input_filename, output_filename);