diff options
-rw-r--r-- | binutils/ChangeLog | 16 | ||||
-rw-r--r-- | binutils/ar.c | 2 | ||||
-rw-r--r-- | binutils/bucomm.c | 36 | ||||
-rw-r--r-- | binutils/bucomm.h | 7 | ||||
-rw-r--r-- | binutils/objcopy.c | 124 |
5 files changed, 165 insertions, 20 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 4fa37ba..d60f6a2 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,19 @@ +2005-06-14 H.J. Lu <hongjiu.lu@intel.com> + + PR 995 + * ar.c (BUFSIZE): Moved to ... + * bucomm.h (BUFSIZE): Here. + + * bucomm.c: Include <assert.h>. + (bfd_get_archive_filename): New. + * bucomm.h (bfd_get_archive_filename): New. + + * objcopy.c (copy_unknown_object): New. + (copy_object): Use bfd_get_archive_filename when reporting input + error. Don't call fatal on unknown arch. + (copy_archive): Call copy_unknown_object on unknown format or + arch. + 2005-06-14 Jakub Jelinek <jakub@redhat.com> * readelf.c (cmalloc, xcmalloc, xcrealloc): New functions. diff --git a/binutils/ar.c b/binutils/ar.c index e8b0379..4e53c78 100644 --- a/binutils/ar.c +++ b/binutils/ar.c @@ -49,8 +49,6 @@ #define O_BINARY 0 #endif -#define BUFSIZE 8192 - /* Kludge declaration from BFD! This is ugly! FIXME! XXX */ struct ar_hdr * diff --git a/binutils/bucomm.c b/binutils/bucomm.c index f29e666..a2caa2f 100644 --- a/binutils/bucomm.c +++ b/binutils/bucomm.c @@ -31,6 +31,7 @@ #include <sys/stat.h> #include <time.h> /* ctime, maybe time_t */ +#include <assert.h> #ifndef HAVE_TIME_T_IN_TIME_H #ifndef HAVE_TIME_T_IN_TYPES_H @@ -475,3 +476,38 @@ get_file_size (const char * file_name) return 0; } + +/* Return the filename in a static buffer. */ + +const char * +bfd_get_archive_filename (bfd *abfd) +{ + static size_t curr = 0; + static char *buf; + size_t needed; + + assert (abfd != NULL); + + if (!abfd->my_archive) + return bfd_get_filename (abfd); + + needed = (strlen (bfd_get_filename (abfd->my_archive)) + + strlen (bfd_get_filename (abfd)) + 3); + if (needed > curr) + { + if (curr) + free (buf); + curr = needed + (needed >> 1); + buf = bfd_malloc (curr); + /* If we can't malloc, fail safe by returning just the file name. + This function is only used when building error messages. */ + if (!buf) + { + curr = 0; + return bfd_get_filename (abfd); + } + } + sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive), + bfd_get_filename (abfd)); + return buf; +} diff --git a/binutils/bucomm.h b/binutils/bucomm.h index aa152fa..8639646 100644 --- a/binutils/bucomm.h +++ b/binutils/bucomm.h @@ -147,7 +147,14 @@ void *alloca (); # define N_(String) (String) #endif +/* Used by ar.c and objcopy.c. */ +#define BUFSIZE 8192 + /* bucomm.c */ + +/* Return the filename in a static buffer. */ +const char *bfd_get_archive_filename (bfd *); + void bfd_nonfatal (const char *); void bfd_fatal (const char *) ATTRIBUTE_NORETURN; diff --git a/binutils/objcopy.c b/binutils/objcopy.c index d8feae6..4dfba3c 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -1120,6 +1120,74 @@ add_redefine_syms_file (const char *filename) free (buf); } +/* Copy unkown object file IBFD onto OBFD. + Returns TRUE upon success, FALSE otherwise. */ + +static bfd_boolean +copy_unknown_object (bfd *ibfd, bfd *obfd) +{ + char *cbuf; + int tocopy; + long ncopied; + long size; + struct stat buf; + + if (bfd_stat_arch_elt (ibfd, &buf) != 0) + { + bfd_nonfatal (bfd_get_archive_filename (ibfd)); + return FALSE; + } + + size = buf.st_size; + if (size < 0) + { + non_fatal (_("stat returns negative size for `%s'"), + bfd_get_archive_filename (ibfd)); + return FALSE; + } + + if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0) + { + bfd_nonfatal (bfd_get_archive_filename (ibfd)); + return FALSE; + } + + if (verbose) + printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"), + bfd_get_archive_filename (ibfd), bfd_get_filename (obfd)); + + cbuf = xmalloc (BUFSIZE); + ncopied = 0; + while (ncopied < size) + { + tocopy = size - ncopied; + if (tocopy > BUFSIZE) + tocopy = BUFSIZE; + + if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd) + != (bfd_size_type) tocopy) + { + bfd_nonfatal (bfd_get_archive_filename (ibfd)); + free (cbuf); + return FALSE; + } + + if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd) + != (bfd_size_type) tocopy) + { + bfd_nonfatal (bfd_get_filename (obfd)); + free (cbuf); + return FALSE; + } + + ncopied += tocopy; + } + + chmod (bfd_get_filename (obfd), buf.st_mode); + free (cbuf); + return TRUE; +} + /* Copy object file IBFD onto OBFD. Returns TRUE upon success, FALSE otherwise. */ @@ -1149,8 +1217,8 @@ copy_object (bfd *ibfd, bfd *obfd) } if (verbose) - printf (_("copy from %s(%s) to %s(%s)\n"), - bfd_get_filename (ibfd), bfd_get_target (ibfd), + printf (_("copy from `%s' [%s] to `%s' [%s]\n"), + bfd_get_archive_filename (ibfd), bfd_get_target (ibfd), bfd_get_filename (obfd), bfd_get_target (obfd)); if (set_start_set) @@ -1173,7 +1241,7 @@ copy_object (bfd *ibfd, bfd *obfd) if (!bfd_set_start_address (obfd, start) || !bfd_set_file_flags (obfd, flags)) { - bfd_nonfatal (bfd_get_filename (ibfd)); + bfd_nonfatal (bfd_get_archive_filename (ibfd)); return FALSE; } } @@ -1186,20 +1254,18 @@ copy_object (bfd *ibfd, bfd *obfd) || bfd_get_arch (ibfd) != bfd_get_arch (obfd))) { if (bfd_get_arch (ibfd) == bfd_arch_unknown) - fatal (_("Unable to recognise the format of the input file %s"), - bfd_get_filename (ibfd)); + non_fatal (_("Unable to recognise the format of the input file `%s'"), + bfd_get_archive_filename (ibfd)); else - { - non_fatal (_("Warning: Output file cannot represent architecture %s"), - bfd_printable_arch_mach (bfd_get_arch (ibfd), - bfd_get_mach (ibfd))); - return FALSE; - } + non_fatal (_("Warning: Output file cannot represent architecture `%s'"), + bfd_printable_arch_mach (bfd_get_arch (ibfd), + bfd_get_mach (ibfd))); + return FALSE; } if (!bfd_set_format (obfd, bfd_get_format (ibfd))) { - bfd_nonfatal (bfd_get_filename (ibfd)); + bfd_nonfatal (bfd_get_archive_filename (ibfd)); return FALSE; } @@ -1385,7 +1451,7 @@ copy_object (bfd *ibfd, bfd *obfd) symsize = bfd_get_symtab_upper_bound (ibfd); if (symsize < 0) { - bfd_nonfatal (bfd_get_filename (ibfd)); + bfd_nonfatal (bfd_get_archive_filename (ibfd)); return FALSE; } @@ -1634,13 +1700,35 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target) RETURN_NONFATAL (output_name); if (bfd_check_format (this_element, bfd_object)) - delete = ! copy_object (this_element, output_bfd); + { + delete = ! copy_object (this_element, output_bfd); - if (!bfd_close (output_bfd)) + if (! delete + || bfd_get_arch (this_element) != bfd_arch_unknown) + { + if (!bfd_close (output_bfd)) + { + bfd_nonfatal (bfd_get_filename (output_bfd)); + /* Error in new object file. Don't change archive. */ + status = 1; + } + } + else + goto copy_unknown_element; + } + else { - bfd_nonfatal (bfd_get_filename (output_bfd)); - /* Error in new object file. Don't change archive. */ - status = 1; + non_fatal (_("Unable to recognise the format of the input file `%s'"), + bfd_get_archive_filename (this_element)); + +copy_unknown_element: + delete = !copy_unknown_object (this_element, output_bfd); + if (!bfd_close_all_done (output_bfd)) + { + bfd_nonfatal (bfd_get_filename (output_bfd)); + /* Error in new object file. Don't change archive. */ + status = 1; + } } if (delete) |