Don't choose plugin target in binutils/

Instead make bfd_check_format try the plugin target first when the
user hasn't supplied a target.

bfd/
	* format.c (bfd_check_format_matches): Try for a plugin target
	match first.
	* targets.c (bfd_find_target): Don't specially treat "plugin".
binutils/
	* ar.c (plugin_target): Delete.
	(open_inarch): Don't set target of archive elements.
	(replace_members): Use target rather than plugin_target when
	opening replacement or additional files.
	* arsup.c (plugin_target): Delete.  Replace all uses with NULL.
	(ar_open): Don't set element target.
	* bucomm.h (set_plugin_target): Delete.
	* nm.c (plugin_target): Delete.
	(display_archive): Don't set element target.
	(display_file): Alway use target when opening file.
	* objcopy.c (copy_archive): Don't use plugin target for output
	elements.
	* NEWS: Mention stricter target checking.
diff --git a/bfd/format.c b/bfd/format.c
index 4dbe863..81e8f1c 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -513,17 +513,39 @@
   if (!bfd_preserve_save (abfd, &preserve, NULL))
     goto err_ret;
 
-  /* First try matching the current target.  The current target may
-     have been set due to a user option, or due to the linker trying
-     optimistically to load input files for the same target as the
-     output, or due to the plugin support setting "plugin", or failing
-     any of those bfd_find_target will have chosen a default target.
-     target_defaulted will be set in the last case, or when "plugin"
-     is the target (even if chosen by user option).  Note that
-     bfd_plugin_no excluding the plugin target condition is an
-     optimisation, and can be removed if desired.  */
+  /* First try matching the plugin target if appropriate.  Next try
+     the current target.  The current target may have been set due to
+     a user option, or due to the linker trying optimistically to load
+     input files for the same target as the output.  Either will
+     have target_defaulted false.  Failing that, bfd_find_target will
+     have chosen a default target, and target_defaulted will be true.  */
   fail_targ = NULL;
 #if BFD_SUPPORTS_PLUGINS
+  if (abfd->format == bfd_object
+      && abfd->target_defaulted
+      && !abfd->is_linker_input
+      && abfd->plugin_format != bfd_plugin_no)
+    {
+      extern const bfd_target plugin_vec;
+
+      if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+	goto err_ret;
+
+      BFD_ASSERT (save_targ != &plugin_vec);
+      abfd->xvec = &plugin_vec;
+      bfd_set_error (bfd_error_no_error);
+      cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
+      if (cleanup)
+	goto ok_ret;
+
+      bfd_reinit (abfd, initial_section_id, &preserve, cleanup);
+      bfd_release (abfd, preserve.marker);
+      preserve.marker = bfd_alloc (abfd, 1);
+      abfd->xvec = save_targ;
+    }
+
+  /* bfd_plugin_no excluding the plugin target is an optimisation.
+     The test can be removed if desired.  */
   if (!(abfd->plugin_format == bfd_plugin_no
 	&& bfd_plugin_target_p (save_targ)))
 #endif
diff --git a/bfd/targets.c b/bfd/targets.c
index a7b0450..c2ee917 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -1572,11 +1572,7 @@
     }
 
   if (abfd)
-    /* Treating "plugin" specially here is due to the fact that some
-       of the binutils magically supply a "plugin" target.  That
-       really is a defaulted target, but unfortunately we can't
-       distinguish it from a user supplied "plugin" target.  */
-    abfd->target_defaulted = strcmp (targname, "plugin") == 0;
+    abfd->target_defaulted = false;
 
   target = find_target (targname);
   if (target == NULL)
diff --git a/binutils/NEWS b/binutils/NEWS
index 5038851..ccda855 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,5 +1,12 @@
 -*- text -*-
 
+* Internal changes to plugin support, and stricter target checking may result
+  in some errors being exposed in user options passed to the various binutils.
+  For example objcopy --target=TARGET now will only work if the input file is
+  for TARGET whereas prior versions of objcopy accepted other target input
+  files and produced a TARGET output.  If you do in fact want the old
+  behaviour the correct usage is objcopy --output-target=TARGET.
+
 * NaCl target support is removed.
 
 Changes in 2.45:
diff --git a/binutils/ar.c b/binutils/ar.c
index 79f40db..a159ac1 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -144,12 +144,6 @@
 
 static int show_help = 0;
 
-#if BFD_SUPPORTS_PLUGINS
-static const char *plugin_target = "plugin";
-#else
-static const char *plugin_target = NULL;
-#endif
-
 static const char *target = NULL;
 
 enum long_option_numbers
@@ -884,7 +878,7 @@
 	  if (! bfd_make_readable (libdeps_bfd))
 	    fatal (_("Cannot make libdeps object readable."));
 
-	  if (bfd_find_target (plugin_target, libdeps_bfd) == NULL)
+	  if (bfd_find_target (target, libdeps_bfd) == NULL)
 	    fatal (_("Cannot reset libdeps record type."));
 
 	  /* Insert our libdeps record in 2nd slot of the list of files
@@ -974,7 +968,6 @@
   bfd *arch;
   char **matching;
   const char *arch_target = target;
-  const struct bfd_target *plugin_vec;
 
   bfd_set_error (bfd_error_no_error);
 
@@ -1064,21 +1057,12 @@
 	}
     }
 
-  /* We didn't open the archive using plugin_target, because the
-     plugin bfd_target does not support archives.  Select
-     plugin_target now for elements so that we can recognise LTO IR
-     files and read IR symbols for use in the archive map.  */
-  plugin_vec = NULL;
-  if (!target && plugin_target)
-    plugin_vec = bfd_find_target (plugin_target, NULL);
-
   /* Open all the archive contents.  */
   last_one = &(arch->archive_next);
   for (next_one = bfd_openr_next_archived_file (arch, NULL);
        next_one;
        next_one = bfd_openr_next_archived_file (arch, next_one))
     {
-      set_plugin_target (next_one, plugin_vec);
       *last_one = next_one;
       last_one = &next_one->archive_next;
     }
@@ -1570,9 +1554,8 @@
 		    }
 		  else
 		    {
-		      const char *targ = target ? target : plugin_target;
 		      replaced = ar_emul_replace (after_bfd, *files_to_move,
-						  targ, verbose);
+						  target, verbose);
 		    }
 		  if (replaced)
 		    {
@@ -1598,8 +1581,7 @@
 	}
       else
         {
-	  const char *targ = target ? target : plugin_target;
-	  changed |= ar_emul_append (after_bfd, *files_to_move, targ,
+	  changed |= ar_emul_append (after_bfd, *files_to_move, target,
 				     verbose, make_thin_archive);
 	}
 
diff --git a/binutils/arsup.c b/binutils/arsup.c
index e71c860..c7b6564 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -41,12 +41,6 @@
 static int temp_fd;
 static FILE *outfile;
 
-#if BFD_SUPPORTS_PLUGINS
-static const char *plugin_target = "plugin";
-#else
-static const char *plugin_target = NULL;
-#endif
-
 static void
 map_over_list (bfd *arch, void (*function) (bfd *, bfd *), struct list *list)
 {
@@ -203,15 +197,8 @@
 	  ptr = &(obfd->archive_head);
 	  element = bfd_openr_next_archived_file (ibfd, NULL);
 
-#if BFD_SUPPORTS_PLUGINS
-	  const struct bfd_target *plugin_vec
-	    = bfd_find_target (plugin_target, NULL);
-#endif
 	  while (element)
 	    {
-#if BFD_SUPPORTS_PLUGINS
-	      set_plugin_target (element, plugin_vec);
-#endif
 	      *ptr = element;
 	      ptr = &element->archive_next;
 	      element = bfd_openr_next_archived_file (ibfd, element);
@@ -270,7 +257,7 @@
 	{
 	  bfd *abfd;
 
-	  abfd = bfd_openr (list->name, plugin_target);
+	  abfd = bfd_openr (list->name, NULL);
 	  if (!abfd)
 	    {
 	      fprintf (stderr, _("%s: can't open file %s\n"),
@@ -397,7 +384,7 @@
 	      if (FILENAME_CMP (bfd_get_filename (member), list->name) == 0)
 		{
 		  /* Found the one to replace.  */
-		  bfd *abfd = bfd_openr (list->name, plugin_target);
+		  bfd *abfd = bfd_openr (list->name, NULL);
 
 		  if (!abfd)
 		    {
@@ -421,7 +408,7 @@
 
 	  if (!found)
 	    {
-	      bfd *abfd = bfd_openr (list->name, plugin_target);
+	      bfd *abfd = bfd_openr (list->name, NULL);
 
 	      fprintf (stderr,_("%s: can't find module file %s\n"),
 		       program_name, list->name);
diff --git a/binutils/bucomm.h b/binutils/bucomm.h
index 54f54d7..9815e71 100644
--- a/binutils/bucomm.h
+++ b/binutils/bucomm.h
@@ -84,19 +84,4 @@
   ((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
 #endif
 
-/* Change ABFD target vector to TARG.  ABFD is an archive element.
-   TARG is plugin_vec, or NULL if plugins are not supported.  */
-static inline void
-set_plugin_target (bfd *abfd, const struct bfd_target *targ)
-{
-  /* Don't change the target for archives like pdb that handle
-     elements specially, as detected by my_archive being NULL.  */
-  if (abfd->my_archive && targ)
-    {
-      abfd->xvec = targ;
-      /* Don't fail if the element isn't recognised by the plugin.  */
-      abfd->target_defaulted = true;
-    }
-}
-
 #endif /* _BUCOMM_H */
diff --git a/binutils/nm.c b/binutils/nm.c
index 130b6e6..8098ed3 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -222,11 +222,6 @@
 static char desc_format[] = "%04x";
 
 static char *target = NULL;
-#if BFD_SUPPORTS_PLUGINS
-static const char *plugin_target = "plugin";
-#else
-static const char *plugin_target = NULL;
-#endif
 
 typedef enum unicode_display_type
 {
@@ -1601,14 +1596,6 @@
   if (print_armap)
     print_symdef_entry (file);
 
-  /* We didn't open the archive using plugin_target, because the
-     plugin bfd_target does not support archives.  Select
-     plugin_target now for elements so that we can recognise LTO IR
-     files and print IR symbols.  */
-  const struct bfd_target *plugin_vec = NULL;
-  if (!target && plugin_target)
-    plugin_vec = bfd_find_target (plugin_target, NULL);
-
   bfd *last_arfile = NULL;
   for (;;)
     {
@@ -1626,8 +1613,6 @@
       if (last_arfile != NULL)
 	bfd_close (last_arfile);
 
-      set_plugin_target (arfile, plugin_vec);
-
       char **matching;
       if (bfd_check_format_matches (arfile, bfd_object, &matching))
 	{
@@ -1660,7 +1645,7 @@
   if (get_file_size (filename) < 1)
     return false;
 
-  file = bfd_openr (filename, target ? target : plugin_target);
+  file = bfd_openr (filename, target);
   if (file == NULL)
     {
       bfd_nonfatal (filename);
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index d88422e..d8648eb 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -3795,14 +3795,8 @@
 	  if (preserve_dates && stat_status == 0)
 	    set_times (output_name, &buf);
 
-	  /* Open the newly created output file and attach to our
-	     list.  We must enable the plugin target here in order to
-	     read IR symbols for the archive map.  */
-	  const char *targ = output_target;
-#if BFD_SUPPORTS_PLUGINS
-	  if (!force_output_target)
-	    targ = "plugin";
-#endif
+	  /* Open the newly created output file and attach to our list.  */
+	  const char *targ = force_output_target ? output_target : NULL;
 	  output_element = bfd_openr (output_name, targ);
 
 	  list->obfd = output_element;