This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Should strip gnore the unknown files in archive?
On Wed, Jun 08, 2005 at 11:03:22AM +0100, Nick Clifton wrote:
> Hi H. J.
>
> >I don't mind error on "strip foo.c". But I don't think error on
> >foo.c in an archive is nice. A warning is better.
>
> Agreed. I assume that you have a patch that does this ?
Here is the patch.
H.J.
---
2005-06-08 H.J. Lu <hongjiu.lu@intel.com>
PR 995
* bucomm.c: Include <assert.h>.
(bfd_archive_filename): New.
* bucomm.h (bfd_archive_filename): New.
* objcopy.c (copy_unknown_object): New.
(copy_object): Use bfd_archive_filename when reporting input
error. Don't call fatal on unknown arch.
(copy_archive): Call copy_unknown_object on unknown format or
arch.
--- binutils/bucomm.c.unknown 2005-05-08 12:01:57.000000000 -0700
+++ binutils/bucomm.c 2005-06-08 11:03:35.000000000 -0700
@@ -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,39 @@ get_file_size (const char * file_name)
return 0;
}
+
+const char *
+bfd_archive_filename (bfd *abfd)
+{
+ assert (abfd != NULL);
+
+ if (abfd->my_archive)
+ {
+ static size_t curr = 0;
+ static char *buf;
+ size_t needed;
+
+ 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;
+ }
+ else
+ return bfd_get_filename (abfd);
+}
--- binutils/bucomm.h.unknown 2005-05-08 12:01:57.000000000 -0700
+++ binutils/bucomm.h 2005-06-08 10:49:40.000000000 -0700
@@ -148,6 +148,8 @@ void *alloca ();
#endif
/* bucomm.c */
+const char *bfd_archive_filename (bfd *);
+
void bfd_nonfatal (const char *);
void bfd_fatal (const char *) ATTRIBUTE_NORETURN;
--- binutils/objcopy.c.unknown 2005-05-08 12:01:59.000000000 -0700
+++ binutils/objcopy.c 2005-06-08 11:48:04.000000000 -0700
@@ -1120,6 +1120,76 @@ add_redefine_syms_file (const char *file
free (buf);
}
+#define BUFSIZE 8192
+
+/* Copy uknown 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_archive_filename (ibfd));
+ return FALSE;
+ }
+
+ size = buf.st_size;
+ if (size < 0)
+ {
+ non_fatal (_("stat returns negative size for `%s'"),
+ bfd_archive_filename (ibfd));
+ return FALSE;
+ }
+
+ if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0)
+ {
+ bfd_nonfatal (bfd_archive_filename (ibfd));
+ return FALSE;
+ }
+
+ if (verbose)
+ printf (_("copy from `%s'(unknown) to `%s'(unknown)\n"),
+ bfd_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_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 +1219,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_archive_filename (ibfd), bfd_get_target (ibfd),
bfd_get_filename (obfd), bfd_get_target (obfd));
if (set_start_set)
@@ -1173,7 +1243,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_archive_filename (ibfd));
return FALSE;
}
}
@@ -1186,20 +1256,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_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_archive_filename (ibfd));
return FALSE;
}
@@ -1385,7 +1453,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_archive_filename (ibfd));
return FALSE;
}
@@ -1634,13 +1702,35 @@ copy_archive (bfd *ibfd, bfd *obfd, cons
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_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)