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(""),"cd");
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 ibfd->archive_head = this_element;
158 while (this_element != (bfd *)NULL) {
160 /* Create an output file for this member */
161 char *output_name = cat(dir, "/",this_element->filename);
162 bfd *output_bfd = bfd_openw(output_name, output_target);
164 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
165 bfd_fatal(output_filename);
167 if (output_bfd == (bfd *)NULL) {
168 bfd_fatal(output_name);
170 if (bfd_check_format(this_element, bfd_object) == true) {
171 copy_object(this_element, output_bfd);
174 bfd_close(output_bfd);
175 /* Now open the newly output file and attatch to our list */
176 output_bfd = bfd_openr(output_name, output_target);
177 /* Mark it for deletion */
181 ptr =&( output_bfd->next);
182 this_element->next = bfd_openr_next_archived_file(ibfd, this_element);
183 this_element = this_element->next;
188 if (!bfd_close(obfd))
189 bfd_fatal(output_filename);
191 /* Now delete all the files that we opened.
192 Construct their names again, unfortunately, but so what;
193 we're about to exit anyway. */
194 for (this_element = ibfd->archive_head;
195 this_element != (bfd *)NULL;
196 this_element = this_element->next)
198 unlink(cat(dir,"/",this_element->filename));
201 if (!bfd_close(ibfd))
202 bfd_fatal(input_filename);
208 copy_file(input_filename, output_filename)
209 char *input_filename;
210 char *output_filename;
214 ibfd = bfd_openr(input_filename, input_target);
216 bfd_fatal(input_filename);
218 if (bfd_check_format(ibfd, bfd_object)) {
219 bfd * obfd = bfd_openw(output_filename, output_target);
221 bfd_fatal(output_filename);
223 copy_object(ibfd, obfd);
225 if (!bfd_close(obfd))
226 bfd_fatal(output_filename);
228 if (!bfd_close(ibfd))
229 bfd_fatal(input_filename);
231 else if (bfd_check_format(ibfd, bfd_archive)) {
232 bfd * obfd = bfd_openw(output_filename, output_target);
234 bfd_fatal(output_filename);
235 copy_archive(ibfd, obfd);
241 /** Actually do the work */
243 setup_sections(ibfd, isection, obfd)
250 osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
251 if (osection == NULL) {
256 if (!bfd_set_section_size(obfd,
258 bfd_section_size(ibfd, isection))) {
263 if (bfd_set_section_vma(obfd,
265 bfd_section_vma(ibfd, isection))
271 if (bfd_set_section_alignment(obfd,
273 bfd_section_alignment(ibfd, isection))
279 if (!bfd_set_section_flags(obfd, osection,
280 bfd_get_section_flags(ibfd, isection))) {
289 fprintf(stderr, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
291 bfd_get_filename(ibfd), bfd_section_name(ibfd, isection),
292 err, bfd_errmsg(bfd_error));
294 } /* setup_sections() */
297 Copy all the section related data from an input section
300 If stripping then don't copy any relocation info
303 copy_sections(ibfd, isection, obfd)
313 osection = bfd_get_section_by_name(obfd,
314 bfd_section_name(ibfd, isection));
316 size = bfd_section_size(ibfd, isection);
321 if (strip == true || get_reloc_upper_bound(ibfd, isection) == 0)
323 bfd_set_reloc(obfd, osection, (arelent **)NULL, 0);
327 relpp = (arelent **) xmalloc(get_reloc_upper_bound(ibfd, isection));
328 relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
329 bfd_set_reloc(obfd, osection, relpp, relcount);
333 if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS)
335 unsigned char *memhunk = (unsigned char *) xmalloc(size);
337 if (!bfd_get_section_contents(ibfd, isection, memhunk, 0, size))
338 bfd_fatal(bfd_get_filename(ibfd));
340 if (!bfd_set_section_contents(obfd, osection, memhunk, 0, size))
341 bfd_fatal(bfd_get_filename(obfd));
354 program_name = argv[0];
356 if (strcmp(program_name,"strip") == 0) {
360 for (i = 1; i < argc; i++)
362 if (argv[i][0] == '-') {
363 switch (argv[i][1]) {
369 input_target = output_target = argv[i];
376 input_target = argv[i];
380 output_target = argv[i];
387 if (input_filename) {
388 output_filename = argv[i];
391 input_filename = argv[i];
396 if (input_filename == (char *) NULL)
399 if (output_target == (char *) NULL)
400 output_target = input_target;
402 /* If there is no destination file then create a temp and rename
403 the result into the input */
405 if (output_filename == (char *)NULL) {
406 char * tmpname = make_tempname(input_filename);
407 copy_file(input_filename, tmpname);
408 output_filename = input_filename;
409 rename(tmpname, input_filename);
412 copy_file(input_filename, output_filename);