-/*** copy.c -- copy object file from input to output, optionally massaging it */
-#include "sysdep.h"
+/* copy.c -- copy object file from input to output, optionally massaging it.
+ Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of GNU Binutils.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
#include "bfd.h"
+#include "sysdep.h"
asymbol **sympp;
char *input_target = NULL;
static boolean strip;
static boolean verbose;
+/* This flag distinguishes between strip and copy:
+ 1 means this is 'strip'; 0 means this is 'copy'.
+ -1 means if we should use argv[0] to decide. */
+extern int is_strip;
+
/* IMPORTS */
extern char *program_name;
extern char *xmalloc();
ibfd->filename, ibfd->xvec->name,
obfd->filename, obfd->xvec->name);
- if ((bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false) ||
+ if ((bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false)
+ ||
(bfd_set_file_flags(obfd, (bfd_get_file_flags(ibfd) &
- ~(HAS_LINENO | HAS_DEBUG | HAS_SYMS | D_PAGED |
- HAS_LOCALS))) == false) ||
- bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false)
- bfd_fatal(bfd_get_filename(ibfd));
+ (HAS_LINENO | HAS_DEBUG |
+ HAS_RELOC | HAS_SYMS | D_PAGED |
+ HAS_LOCALS))) == false)) {
+ bfd_fatal(bfd_get_filename(ibfd));
+ }
/* Copy architecture of input file to output file */
- if (!bfd_set_arch_mach(obfd, bfd_get_architecture(ibfd),
- bfd_get_machine(ibfd))) {
+ if (!bfd_set_arch_mach(obfd, bfd_get_arch(ibfd),
+ bfd_get_mach(ibfd))) {
fprintf(stderr, "Output file cannot represent architecture %s\n",
- bfd_printable_arch_mach(bfd_get_architecture(ibfd),
- bfd_get_machine(ibfd)));
+ bfd_printable_arch_mach(bfd_get_arch(ibfd),
+ bfd_get_mach(ibfd)));
}
if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
{
sympp = (asymbol **) xmalloc(get_symtab_upper_bound(ibfd));
symcount = bfd_canonicalize_symtab(ibfd, sympp);
- bfd_set_symtab(obfd, sympp, strip == true ? 0 : symcount);
+ bfd_set_symtab(obfd, sympp, is_strip ? 0 : symcount);
/*
bfd mandates that all output sections be created and sizes set before
bfd *ibfd;
bfd *obfd;
{
- bfd **ptr =&( obfd->archive_head);
+ bfd **ptr = &obfd->archive_head;
bfd *this_element;
/* Read each archive element in turn from the input, copy the
contents to a temp file, and keep the temp file handle */
- char *dir = cat("./",make_tempname(this_element->filename),"copy-dir");
+ char *dir = cat("./#",make_tempname(""),"cd");
/* Make a temp directory to hold the contents */
mkdir(dir,0777);
obfd->has_armap = ibfd->has_armap;
this_element = bfd_openr_next_archived_file(ibfd, NULL);
+ ibfd->archive_head = this_element;
while (this_element != (bfd *)NULL) {
/* Create an output file for this member */
char *output_name = cat(dir, "/",this_element->filename);
bfd *output_bfd = bfd_openw(output_name, output_target);
-
+
if (!bfd_set_format(obfd, bfd_get_format(ibfd)))
bfd_fatal(output_filename);
*ptr = output_bfd;
- ptr =&( output_bfd->next);
- this_element = bfd_openr_next_archived_file(ibfd, this_element);
+ ptr = &output_bfd->next;
+ this_element->next = bfd_openr_next_archived_file(ibfd, this_element);
+ this_element = this_element->next;
}
*ptr = (bfd *)NULL;
if (!bfd_close(obfd))
bfd_fatal(output_filename);
- /* Now delete all the files that we opened
- We can't use the names in the obfd list since they may have been
- trampled by the archive output code
- */
+ /* Now delete all the files that we opened.
+ Construct their names again, unfortunately, but so what;
+ we're about to exit anyway. */
for (this_element = ibfd->archive_head;
this_element != (bfd *)NULL;
this_element = this_element->next)
{
unlink(cat(dir,"/",this_element->filename));
}
- unlink(dir);
+ rmdir(dir);
if (!bfd_close(ibfd))
bfd_fatal(input_filename);
}
static
-boolean
+void
copy_file(input_filename, output_filename)
char *input_filename;
char *output_filename;
{
- bfd *ibfd;
-
+ bfd *ibfd;
- ibfd = bfd_openr(input_filename, input_target);
- if (ibfd == NULL)
- bfd_fatal(input_filename);
+ ibfd = bfd_openr(input_filename, input_target);
+ if (ibfd == NULL)
+ bfd_fatal(input_filename);
- if (bfd_check_format(ibfd, bfd_object)) {
- bfd * obfd = bfd_openw(output_filename, output_target);
- if (obfd == NULL)
- bfd_fatal(output_filename);
+ if (bfd_check_format(ibfd, bfd_object)) {
+ bfd * obfd = bfd_openw(output_filename, output_target);
+ if (obfd == NULL)
+ bfd_fatal(output_filename);
- copy_object(ibfd, obfd);
+ copy_object(ibfd, obfd);
- if (!bfd_close(obfd))
- bfd_fatal(output_filename);
-
- if (!bfd_close(ibfd))
- bfd_fatal(input_filename);
- }
- else if (bfd_check_format(ibfd, bfd_archive)) {
- bfd * obfd = bfd_openw(output_filename, output_target);
- if (obfd == NULL)
- bfd_fatal(output_filename);
+ if (ibfd->flags & EXEC_P)
+ obfd->flags |= EXEC_P;
+ if (!bfd_close(obfd))
+ bfd_fatal(output_filename);
- copy_archive(ibfd, obfd);
- }
+ if (!bfd_close(ibfd))
+ bfd_fatal(input_filename);
+ }
+ else if (bfd_check_format(ibfd, bfd_archive)) {
+ bfd * obfd = bfd_openw(output_filename, output_target);
+ if (obfd == NULL)
+ bfd_fatal(output_filename);
+ copy_archive(ibfd, obfd);
+ }
}
{
sec_ptr osection;
char *err;
- osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
+
+ osection = bfd_get_section_by_name(obfd, bfd_section_name(ibfd, isection));
if (osection == NULL) {
- err = "making";
- goto loser;
+ osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
+ if (osection == NULL) {
+ err = "making";
+ goto loser;
+ }
}
if (!bfd_set_section_size(obfd,
exit(1);
} /* setup_sections() */
+/*
+Copy all the section related data from an input section
+to an output section
+
+If stripping then don't copy any relocation info
+*/
static void
copy_sections(ibfd, isection, obfd)
bfd *ibfd;
sec_ptr isection;
bfd *obfd;
{
- static unsigned char *memhunk = NULL;
- arelent **relpp;
- int relcount;
- sec_ptr osection;
- unsigned long size;
- osection = bfd_get_section_by_name(obfd,
- bfd_section_name(ibfd, isection));
-
- size = bfd_section_size(ibfd, isection);
- if (size == 0)
- return;
+ arelent **relpp;
+ int relcount;
+ sec_ptr osection;
+ bfd_size_type size;
+ osection = bfd_get_section_by_name(obfd,
+ bfd_section_name(ibfd, isection));
- if (get_reloc_upper_bound(ibfd, isection) != 0) {
- relpp = (arelent **) xmalloc(get_reloc_upper_bound(ibfd, isection));
+ size = isection->size;
- relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
+ if (size == 0)
+ return;
- bfd_set_reloc(obfd, osection, relpp, relcount);
+ if (is_strip || get_reloc_upper_bound(ibfd, isection) == 0)
+ {
+ bfd_set_reloc(obfd, osection, (arelent **)NULL, 0);
+ }
+ else
+ {
+ relpp = (arelent **) xmalloc(get_reloc_upper_bound(ibfd, isection));
+ relcount = bfd_canonicalize_reloc(ibfd, isection, relpp, sympp);
+ bfd_set_reloc(obfd, osection, relpp, relcount);
}
- if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS) {
- memhunk = (unsigned char *) xmalloc(size);
- /* now we have enough memory, just do it: */
- if (!bfd_get_section_contents(ibfd, isection, memhunk, 0, size))
- bfd_fatal(bfd_get_filename(ibfd));
- if (!bfd_set_section_contents(obfd, osection, memhunk, 0, size))
- bfd_fatal(bfd_get_filename(obfd));
- } /* only if the section has contents. */
+ if (bfd_get_section_flags(ibfd, isection) & SEC_HAS_CONTENTS)
+ {
+ PTR memhunk = (PTR) xmalloc((unsigned)size);
+
+ if (!bfd_get_section_contents(ibfd, isection, memhunk, (file_ptr) 0, size))
+ bfd_fatal(bfd_get_filename(ibfd));
+
+ if (!bfd_set_section_contents(obfd, osection, memhunk, (file_ptr)0, size))
+ bfd_fatal(bfd_get_filename(obfd));
+ free(memhunk);
+ }
+
- free(memhunk);
}
int
main(argc, argv)
int argc;
char *argv[];
{
- int i;
-
-
- program_name = argv[0];
-
- if (strcmp(program_name,"strip") == 0) {
- strip = true;
- }
-
- for (i = 1; i < argc; i++)
- {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'v':
- verbose = true;
- break;
- case 'b':
- i++;
- input_target = output_target = argv[i];
- break;
- case 'S':
- strip = true;
- break;
- case 's':
- i++;
- input_target = argv[i];
- break;
- case 'd':
- i++;
- output_target = argv[i];
- break;
- default:
- usage();
- }
- }
- else {
- if (input_filename) {
- output_filename = argv[i];
- }
- else {
- input_filename = argv[i];
- }
- }
+ int i;
+
+ program_name = argv[0];
+
+ bfd_init();
+
+ if (is_strip < 0) {
+ i = strlen (program_name);
+ is_strip = (i >= 5 && strcmp(program_name+i-5,"strip"));
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 'v':
+ verbose = true;
+ break;
+ case 'b':
+ i++;
+ input_target = output_target = argv[i];
+ break;
+ case 'S':
+ is_strip = 1;
+ break;
+ case 's':
+ i++;
+ input_target = argv[i];
+ break;
+ case 'd':
+ i++;
+ output_target = argv[i];
+ break;
+ default:
+ usage();
}
-
- if (input_filename == (char *) NULL)
- usage();
-
- if (output_target == (char *) NULL)
- output_target = input_target;
-
- /* If there is no destination file then create a temp and rename
- the result into the input */
-
- if (output_filename == (char *)NULL) {
- char * tmpname = make_tempname(input_filename);
- if (copy_file(input_filename, tmpname)) {
- output_filename = input_filename;
- rename(tmpname, input_filename);
- return 0;
+ }
+ else {
+ if (input_filename) {
+ output_filename = argv[i];
}
- }
- else if (copy_file(input_filename, output_filename))
- {
- return 0;
+ else {
+ input_filename = argv[i];
}
+ }
+ }
-
- return 1;
+ if (input_filename == (char *) NULL)
+ usage();
+
+ if (output_target == (char *) NULL)
+ output_target = input_target;
+
+ /* If there is no destination file then create a temp and rename
+ the result into the input */
+
+ if (output_filename == (char *)NULL) {
+ char * tmpname = make_tempname(input_filename);
+ copy_file(input_filename, tmpname);
+ output_filename = input_filename;
+ rename(tmpname, input_filename);
+ }
+ else {
+ copy_file(input_filename, output_filename);
+ }
+ return 0;
}