1 /*** copy.c -- copy object file from input to output, optionally
8 char *input_target = NULL;
9 char *output_target = NULL;
10 char *input_filename = NULL;
11 char *output_filename = NULL;
14 static void setup_sections();
15 static void copy_sections();
17 static boolean verbose;
20 extern char *program_name;
21 extern char *xmalloc();
28 "Usage %s [-S][-s srcfmt] [-d dtfmt] [-b bothfmts] infile [outfile]\n",
34 /* Create a temp file in the same directory as supplied */
37 make_tempname(filename)
40 static char template[] = "stXXXXXX";
42 char * slash = strrchr( filename, '/' );
43 if (slash != (char *)NULL){
45 tmpname = xmalloc(strlen(filename) + sizeof(template) + 1 );
46 strcpy(tmpname, filename);
47 strcat(tmpname, "/" );
48 strcat(tmpname, template);
52 tmpname = xmalloc(sizeof(template));
53 strcpy(tmpname, template);
60 All the symbols have been read in and point to their owning input section.
61 They have been relocated to that they are all relative to the base of
62 their owning section. On the way out, all the symbols will be relocated to
63 their new location in the output file, through some complex sums.
67 mangle_sections(ibfd, obfd)
71 asection *current = ibfd->sections;
72 for (; current != NULL; current = current->next) {
73 current->output_section = bfd_get_section_by_name(obfd, current->name);
74 current->output_offset = 0;
80 copy_object(ibfd, obfd)
85 unsigned int symcount;
88 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
89 bfd_fatal(output_filename);
93 printf("copy from %s(%s) to %s(%s)\n",
94 ibfd->filename, ibfd->xvec->name,
95 obfd->filename, obfd->xvec->name);
97 if ((bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false)
99 (bfd_set_file_flags(obfd, (bfd_get_file_flags(ibfd) &
100 (HAS_LINENO | HAS_DEBUG |
101 HAS_RELOC | HAS_SYMS | D_PAGED |
102 HAS_LOCALS))) == false)) {
103 bfd_fatal(bfd_get_filename(ibfd));
106 /* Copy architecture of input file to output file */
107 if (!bfd_set_arch_mach(obfd, bfd_get_architecture(ibfd),
108 bfd_get_machine(ibfd))) {
109 fprintf(stderr, "Output file cannot represent architecture %s\n",
110 bfd_printable_arch_mach(bfd_get_architecture(ibfd),
111 bfd_get_machine(ibfd)));
113 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
115 bfd_fatal(ibfd->filename);
118 sympp = (asymbol **) xmalloc(get_symtab_upper_bound(ibfd));
119 symcount = bfd_canonicalize_symtab(ibfd, sympp);
121 bfd_set_symtab(obfd, sympp, strip == true ? 0 : symcount);
124 bfd mandates that all output sections be created and sizes set before
125 any output is done. Thus, we traverse all sections twice.
127 bfd_map_over_sections(ibfd, setup_sections, (void *) obfd);
128 bfd_map_over_sections(ibfd, copy_sections, (void *) obfd);
129 mangle_sections(ibfd, obfd);
138 int size = strlen(a) + strlen(b) + strlen(c);
139 char *r = xmalloc(size+1);
147 copy_archive(ibfd, obfd)
151 bfd **ptr = &obfd->archive_head;
153 /* Read each archive element in turn from the input, copy the
154 contents to a temp file, and keep the temp file handle */
155 char *dir = cat("./#",make_tempname(""),"cd");
157 /* Make a temp directory to hold the contents */
159 obfd->has_armap = ibfd->has_armap;
160 this_element = bfd_openr_next_archived_file(ibfd, NULL);
161 ibfd->archive_head = this_element;
162 while (this_element != (bfd *)NULL) {
164 /* Create an output file for this member */
165 char *output_name = cat(dir, "/",this_element->filename);
166 bfd *output_bfd = bfd_openw(output_name, output_target);
168 if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
169 bfd_fatal(output_filename);
171 if (output_bfd == (bfd *)NULL) {
172 bfd_fatal(output_name);
174 if (bfd_check_format(this_element, bfd_object) == true) {
175 copy_object(this_element, output_bfd);
178 bfd_close(output_bfd);
179 /* Now open the newly output file and attatch to our list */
180 output_bfd = bfd_openr(output_name, output_target);
181 /* Mark it for deletion */
185 ptr = &output_bfd->next;
186 this_element->next = bfd_openr_next_archived_file(ibfd, this_element);
187 this_element = this_element->next;
192 if (!bfd_close(obfd))
193 bfd_fatal(output_filename);
195 /* Now delete all the files that we opened.
196 Construct their names again, unfortunately, but so what;
197 we're about to exit anyway. */
198 for (this_element = ibfd->archive_head;
199 this_element != (bfd *)NULL;
200 this_element = this_element->next)
202 unlink(cat(dir,"/",this_element->filename));
205 if (!bfd_close(ibfd))
206 bfd_fatal(input_filename);
212 copy_file(input_filename, output_filename)
213 char *input_filename;
214 char *output_filename;
218 ibfd = bfd_openr(input_filename, input_target);
220 bfd_fatal(input_filename);
222 if (bfd_check_format(ibfd, bfd_object)) {
223 bfd * obfd = bfd_openw(output_filename, output_target);
225 bfd_fatal(output_filename);
227 copy_object(ibfd, obfd);
229 if (!bfd_close(obfd))
230 bfd_fatal(output_filename);
232 if (!bfd_close(ibfd))
233 bfd_fatal(input_filename);
235 else if (bfd_check_format(ibfd, bfd_archive)) {
236 bfd * obfd = bfd_openw(output_filename, output_target);
238 bfd_fatal(output_filename);
239 copy_archive(ibfd, obfd);
245 /** Actually do the work */
247 setup_sections(ibfd, isection, obfd)
254 osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
255 if (osection == NULL) {
260 if (!bfd_set_section_size(obfd,
262 bfd_section_size(ibfd, isection))) {
267 if (bfd_set_section_vma(obfd,
269 bfd_section_vma(ibfd, isection))
275 if (bfd_set_section_alignment(obfd,
277 bfd_section_alignment(ibfd, isection))
283 if (!bfd_set_section_flags(obfd, osection,
284 bfd_get_section_flags(ibfd, isection))) {
293 fprintf(stderr, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
295 bfd_get_filename(ibfd), bfd_section_name(ibfd, isection),
296 err, bfd_errmsg(bfd_error));
298 } /* setup_sections() */
301 Copy all the section related data from an input section
304 If stripping then don't copy any relocation info
307 copy_sections(ibfd, isection, obfd)
317 osection = bfd_get_section_by_name(obfd,
318 bfd_section_name(ibfd, isection));
320 size = isection->size;
325 if (strip == true || get_reloc_upper_bound(ibfd, isection) == 0)
327 bfd_set_reloc(obfd, osection, (arelent **)NULL, 0);
331 relpp = (arelent **) xmalloc(get_reloc_upper_bound(ibfd, isection));
332 relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
333 bfd_set_reloc(obfd, osection, relpp, relcount);
337 if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS)
339 PTR memhunk = (PTR) xmalloc((unsigned)size);
341 if (!bfd_get_section_contents(ibfd, isection, memhunk, (file_ptr) 0, size))
342 bfd_fatal(bfd_get_filename(ibfd));
344 if (!bfd_set_section_contents(obfd, osection, memhunk, (file_ptr)0, size))
345 bfd_fatal(bfd_get_filename(obfd));
358 program_name = argv[0];
360 if (strcmp(program_name,"strip") == 0) {
364 for (i = 1; i < argc; i++)
366 if (argv[i][0] == '-') {
367 switch (argv[i][1]) {
373 input_target = output_target = argv[i];
380 input_target = argv[i];
384 output_target = argv[i];
391 if (input_filename) {
392 output_filename = argv[i];
395 input_filename = argv[i];
400 if (input_filename == (char *) NULL)
403 if (output_target == (char *) NULL)
404 output_target = input_target;
406 /* If there is no destination file then create a temp and rename
407 the result into the input */
409 if (output_filename == (char *)NULL) {
410 char * tmpname = make_tempname(input_filename);
411 copy_file(input_filename, tmpname);
412 output_filename = input_filename;
413 rename(tmpname, input_filename);
416 copy_file(input_filename, output_filename);