PR binutils/3110
authorNick Clifton <nickc@redhat.com>
Mon, 11 Sep 2006 14:40:39 +0000 (14:40 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 11 Sep 2006 14:40:39 +0000 (14:40 +0000)
* objcopy.c (copy_archive): Add new parameter: force_output_target. If not
  true, then perserve the file formats of each copied archive element,
  otherwise force them to be one specific file format.
  (copy_file): Compute force_output_target parameter to pass to copy_archive.

binutils/ChangeLog
binutils/objcopy.c

index b36b87530da4cd879b5e3bef141d72a7d74cd610..b711b7e1c81a1872733c196106abc254865eb7d6 100644 (file)
@@ -1,3 +1,13 @@
+2006-09-09  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/3110
+       * objcopy.c (copy_archive): Add new parameter:
+       force_output_target.  If not true, then perserve the file formats
+       of each copied archive element, otherwise force them to be one
+       specific file format.
+       (copy_file): Compute force_output_target parameter to pass to
+       copy_archive. 
+
 2006-09-05  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/3166
index 8db5ef020022c457f45caef32fd8b269bb46427e..2e2ccef6e5ddaef0c165f22c9a4cebb3a12c590a 100644 (file)
@@ -1730,10 +1730,14 @@ copy_object (bfd *ibfd, bfd *obfd)
 #endif
 
 /* Read each archive element in turn from IBFD, copy the
-   contents to temp file, and keep the temp file handle.  */
+   contents to temp file, and keep the temp file handle.
+   If 'force_output_target' is TRUE then make sure that
+   all elements in the new archive are of the type
+   'output_target'.  */
 
 static void
-copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
+copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
+             bfd_boolean force_output_target)
 {
   struct name_list
     {
@@ -1789,7 +1793,6 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
                                bfd_get_filename (this_element), (char *) 0);
        }
 
-      output_bfd = bfd_openw (output_name, output_target);
       if (preserve_dates)
        {
          stat_status = bfd_stat_arch_elt (this_element, &buf);
@@ -1805,11 +1808,18 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
       l->obfd = NULL;
       list = l;
 
-      if (output_bfd == NULL)
-       RETURN_NONFATAL (output_name);
-
       if (bfd_check_format (this_element, bfd_object))
        {
+         /* PR binutils/3110: Cope with archives
+            containing multiple target types.  */
+         if (force_output_target)
+           output_bfd = bfd_openw (output_name, output_target);
+         else
+           output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
+
+         if (output_bfd == NULL)
+           RETURN_NONFATAL (output_name);
+
          delete = ! copy_object (this_element, output_bfd);
 
          if (! delete
@@ -1830,6 +1840,7 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
          non_fatal (_("Unable to recognise the format of the input file `%s'"),
                     bfd_get_archive_filename (this_element));
 
+         output_bfd = bfd_openw (output_name, output_target);
 copy_unknown_element:
          delete = !copy_unknown_object (this_element, output_bfd);
          if (!bfd_close_all_done (output_bfd))
@@ -1911,18 +1922,24 @@ copy_file (const char *input_filename, const char *output_filename,
 
   if (bfd_check_format (ibfd, bfd_archive))
     {
+      bfd_boolean force_output_target;
       bfd *obfd;
 
       /* bfd_get_target does not return the correct value until
          bfd_check_format succeeds.  */
       if (output_target == NULL)
-       output_target = bfd_get_target (ibfd);
+       {
+         output_target = bfd_get_target (ibfd);
+         force_output_target = FALSE;
+       }
+      else
+       force_output_target = TRUE;
 
       obfd = bfd_openw (output_filename, output_target);
       if (obfd == NULL)
        RETURN_NONFATAL (output_filename);
 
-      copy_archive (ibfd, obfd, output_target);
+      copy_archive (ibfd, obfd, output_target, force_output_target);
     }
   else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
     {