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;
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);
236 copy_archive(ibfd, obfd);
242 /** Actually do the work */
244 setup_sections(ibfd, isection, obfd)
251 osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
252 if (osection == NULL) {
257 if (!bfd_set_section_size(obfd,
259 bfd_section_size(ibfd, isection))) {
264 if (bfd_set_section_vma(obfd,
266 bfd_section_vma(ibfd, isection))
272 if (bfd_set_section_alignment(obfd,
274 bfd_section_alignment(ibfd, isection))
280 if (!bfd_set_section_flags(obfd, osection,
281 bfd_get_section_flags(ibfd, isection))) {
290 fprintf(stderr, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
292 bfd_get_filename(ibfd), bfd_section_name(ibfd, isection),
293 err, bfd_errmsg(bfd_error));
295 } /* setup_sections() */
298 copy_sections(ibfd, isection, obfd)
303 static unsigned char *memhunk = NULL;
308 osection = bfd_get_section_by_name(obfd,
309 bfd_section_name(ibfd, isection));
311 size = bfd_section_size(ibfd, isection);
316 if (get_reloc_upper_bound(ibfd, isection) != 0) {
317 relpp = (arelent **) xmalloc(get_reloc_upper_bound(ibfd, isection));
319 relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
321 bfd_set_reloc(obfd, osection, relpp, relcount);
324 if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS) {
325 memhunk = (unsigned char *) xmalloc(size);
326 /* now we have enough memory, just do it: */
327 if (!bfd_get_section_contents(ibfd, isection, memhunk, 0, size))
328 bfd_fatal(bfd_get_filename(ibfd));
330 if (!bfd_set_section_contents(obfd, osection, memhunk, 0, size))
331 bfd_fatal(bfd_get_filename(obfd));
332 } /* only if the section has contents. */
344 program_name = argv[0];
346 if (strcmp(program_name,"strip") == 0) {
350 for (i = 1; i < argc; i++)
352 if (argv[i][0] == '-') {
353 switch (argv[i][1]) {
359 input_target = output_target = argv[i];
366 input_target = argv[i];
370 output_target = argv[i];
377 if (input_filename) {
378 output_filename = argv[i];
381 input_filename = argv[i];
386 if (input_filename == (char *) NULL)
389 if (output_target == (char *) NULL)
390 output_target = input_target;
392 /* If there is no destination file then create a temp and rename
393 the result into the input */
395 if (output_filename == (char *)NULL) {
396 char * tmpname = make_tempname(input_filename);
397 if (copy_file(input_filename, tmpname)) {
398 output_filename = input_filename;
399 rename(tmpname, input_filename);
403 else if (copy_file(input_filename, output_filename))