--- /dev/null
+*** binutils/objcopy.c 5 Sep 2006 08:22:27 -0000 1.98
+--- binutils/objcopy.c 8 Sep 2006 15:01:35 -0000
+*************** copy_object (bfd *ibfd, bfd *obfd)
+*** 1730,1739 ****
+ #endif
+
+ /* Read each archive element in turn from IBFD, copy the
+! contents to temp file, and keep the temp file handle. */
+
+ static void
+! copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
+ {
+ struct name_list
+ {
+--- 1730,1743 ----
+ #endif
+
+ /* Read each archive element in turn from IBFD, copy the
+! 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,
+! bfd_boolean force_output_target)
+ {
+ struct name_list
+ {
+*************** copy_archive (bfd *ibfd, bfd *obfd, cons
+*** 1789,1795 ****
+ 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);
+--- 1793,1798 ----
+*************** copy_archive (bfd *ibfd, bfd *obfd, cons
+*** 1805,1815 ****
+ l->obfd = NULL;
+ list = l;
+
+- if (output_bfd == NULL)
+- RETURN_NONFATAL (output_name);
+-
+ if (bfd_check_format (this_element, bfd_object))
+ {
+ delete = ! copy_object (this_element, output_bfd);
+
+ if (! delete
+--- 1808,1825 ----
+ l->obfd = NULL;
+ list = l;
+
+ 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
+*************** copy_archive (bfd *ibfd, bfd *obfd, cons
+*** 1830,1835 ****
+--- 1840,1846 ----
+ 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))
+*************** copy_file (const char *input_filename, c
+*** 1911,1928 ****
+
+ if (bfd_check_format (ibfd, bfd_archive))
+ {
+ 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);
+
+ obfd = bfd_openw (output_filename, output_target);
+ if (obfd == NULL)
+ RETURN_NONFATAL (output_filename);
+
+! copy_archive (ibfd, obfd, output_target);
+ }
+ else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
+ {
+--- 1922,1945 ----
+
+ 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);
+! 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, force_output_target);
+ }
+ else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
+ {