[binutils-gdb] archives and plugin target

Alan Modra amodra@sourceware.org
Fri Aug 15 22:08:31 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=46cd7e0dc8439b3f3bab1be553a9bea9a1bb5fe9

commit 46cd7e0dc8439b3f3bab1be553a9bea9a1bb5fe9
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Aug 12 22:46:36 2025 +0930

    archives and plugin target
    
    Automatically choosing "plugin" for the archive target when plugins
    are enabled can result in making archives as specified by the plugin
    target vec, ie. COFF style archives (also used by most ELF
    binutils targets).  This is wrong for aix, hpux, vms, aout, macho
    and possibly other targets, if compatibility with target system
    archives matters.
    
    This patch removes archive support entirely from the plugin target.
    That means an archive will never get past bfd_check_format with a
    target of plugin_vec, even if it is opened using "plugin".  Instead,
    archives will have their elements opened using the plugin target
    selected is such a way that the plugin target will be tried first in
    bfd_check_format and then continue to try other targets if that fails.
    
    The patch tries to avoid opening archives using "plugin" because that
    is guaranteed to fail the first target check in bfd_check_format, but
    mm.c still does so, and nested archives will also be opened using
    "plugin".
    
    The patch also fixes poor arsup.c plugin support.
    
    bfd/
            * plugin.c (plugin_vec): Remove archive support.
            * configure.ac: Remove plugin archive warning, and don't disable
            plugins by default on anything but aout targets.
            * configure: Regenerate.
    binutils/
            * bucomm.h (set_plugin_target): New inline function.
            * ar.c: Remove unneeded forward declarations.
            (open_inarch): Don't use "plugin" if defaulting target when
            opening an archive, use "plugin" when opening elements.
            (replace_members): Use "plugin" when opening replacement or
            additional elements.
            * arsup.c: Remove unneeded forward declarations.
            (plugin_target): New.
            (ar_open): Don't open archives using "plugin", use it when
            opening elements.
            (ar_addmod): Use plugin_target.
            (ar_replace): Use plugin_target when opening replacement or
            additional elements.
            (ar_extract): Don't bfd_openr.
            * nm.c (display_archive): Open archive elements using the
            "plugin" target.

Diff:
---
 bfd/configure     | 11 -----------
 bfd/configure.ac  | 10 ----------
 bfd/plugin.c      | 12 ++++--------
 binutils/ar.c     | 40 +++++++++++++++++++++++-----------------
 binutils/arsup.c  | 33 ++++++++++++++++-----------------
 binutils/bucomm.h | 16 ++++++++++++++++
 binutils/nm.c     | 10 ++++++++++
 7 files changed, 69 insertions(+), 63 deletions(-)

diff --git a/bfd/configure b/bfd/configure
index 28ac5ccfbe5..4bd81d300ed 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -11867,7 +11867,6 @@ fi
 
 
 case "${target}" in
-    hppa*64*-*-*) ;;
     *-*-*aout*| i[3-7]86-*-msdos* | ns32k-*-* | pdp11-*-*)
 	if test "$plugins" = "yes"; then
 	    if test "${enable_plugins+set}" = set; then
@@ -11877,16 +11876,6 @@ $as_echo "$as_me: WARNING: Enabling plugins for AOUT is experimental" >&2;}
 		plugins=no
 	    fi
 	fi ;;
-    hppa*-*-hpux* | *-*-*vms* | \
-    powerpc*-*-aix* | powerpc-*-beos* | powerpc-*-macos* | rs6000-*-*)
-	if test "$plugins" = "yes"; then
-	    if test "${enable_plugins+set}" = set; then
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Enabling plugins may result in ar creating non-standard archives for ${target}" >&5
-$as_echo "$as_me: WARNING: Enabling plugins may result in ar creating non-standard archives for ${target}" >&2;}
-	    else
-		plugins=no
-	    fi
-	fi ;;
 esac
 
  if test "$plugins" = "yes"; then
diff --git a/bfd/configure.ac b/bfd/configure.ac
index 502c526b606..14488757874 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -45,7 +45,6 @@ ACX_LARGEFILE
 
 changequote(,)dnl
 case "${target}" in
-    hppa*64*-*-*) ;;
     *-*-*aout*| i[3-7]86-*-msdos* | ns32k-*-* | pdp11-*-*)
 changequote([,])dnl
 	if test "$plugins" = "yes"; then
@@ -55,15 +54,6 @@ changequote([,])dnl
 		plugins=no
 	    fi
 	fi ;;
-    hppa*-*-hpux* | *-*-*vms* | \
-    powerpc*-*-aix* | powerpc-*-beos* | powerpc-*-macos* | rs6000-*-*)
-	if test "$plugins" = "yes"; then
-	    if test "${enable_plugins+set}" = set; then
-		AC_MSG_WARN(Enabling plugins may result in ar creating non-standard archives for ${target})
-	    else
-		plugins=no
-	    fi
-	fi ;;
 esac
 
 AM_CONDITIONAL(PLUGINS, test "$plugins" = "yes")
diff --git a/bfd/plugin.c b/bfd/plugin.c
index 733e7f0f322..2be384d8ef5 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -1002,30 +1002,26 @@ const bfd_target plugin_vec =
   {				/* bfd_check_format.  */
     _bfd_dummy_target,
     bfd_plugin_object_p,
-    bfd_generic_archive_p,
+    _bfd_dummy_target,
     _bfd_dummy_target
   },
   {				/* bfd_set_format.  */
     _bfd_bool_bfd_false_error,
     _bfd_bool_bfd_false_error,
-    _bfd_generic_mkarchive,
+    _bfd_bool_bfd_false_error,
     _bfd_bool_bfd_false_error,
   },
   {				/* bfd_write_contents.  */
     _bfd_bool_bfd_false_error,
     _bfd_bool_bfd_false_error,
-    _bfd_write_archive_contents,
+    _bfd_bool_bfd_false_error,
     _bfd_bool_bfd_false_error,
   },
 
   BFD_JUMP_TABLE_GENERIC (bfd_plugin),
   BFD_JUMP_TABLE_COPY (bfd_plugin),
   BFD_JUMP_TABLE_CORE (bfd_plugin),
-#ifdef USE_64_BIT_ARCHIVE
-  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_64_bit),
-#else
-  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
-#endif
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
   BFD_JUMP_TABLE_SYMBOLS (bfd_plugin),
   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
   BFD_JUMP_TABLE_WRITE (bfd_plugin),
diff --git a/binutils/ar.c b/binutils/ar.c
index 3cac3f3fb26..79f40db991c 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -42,12 +42,9 @@
 #define EXT_NAME_LEN 6		/* Ditto for *NIX.  */
 #endif
 
-/* Static declarations.  */
+/* Forward declarations.  */
 
-static void mri_emul (void);
 static const char *normalize (const char *, bfd *);
-static void remove_output (void);
-static void map_over_members (bfd *, void (*)(bfd *), char **, int);
 static void print_contents (bfd * member);
 static void delete_members (bfd *, char **files_to_delete);
 
@@ -58,8 +55,7 @@ static void print_descr (bfd * abfd);
 static void write_archive (bfd *);
 static int  ranlib_only (const char *archname);
 static int  ranlib_touch (const char *archname);
-static void usage (int);
-

+
 /** Globals and flags.  */
 
 static int mri_mode;
@@ -977,12 +973,11 @@ open_inarch (const char *archive_filename, const char *file)
   struct stat sbuf;
   bfd *arch;
   char **matching;
+  const char *arch_target = target;
+  const struct bfd_target *plugin_vec;
 
   bfd_set_error (bfd_error_no_error);
 
-  if (target == NULL)
-    target = plugin_target;
-
   if (stat (archive_filename, &sbuf) != 0)
     {
 #if !defined(__GO32__) || defined(__DJGPP__)
@@ -1008,16 +1003,16 @@ open_inarch (const char *archive_filename, const char *file)
 
       /* If the target isn't set, try to figure out the target to use
 	 for the archive from the first object on the list.  */
-      if (target == NULL && file != NULL)
+      if (arch_target == NULL && file != NULL)
 	{
 	  bfd *obj;
 
-	  obj = bfd_openr (file, target);
+	  obj = bfd_openr (file, arch_target);
 	  if (obj != NULL)
 	    {
 	      if (bfd_check_format (obj, bfd_object)
 		  && bfd_target_supports_archives (obj))
-		target = bfd_get_target (obj);
+		arch_target = bfd_get_target (obj);
 	      (void) bfd_close (obj);
 	    }
 	}
@@ -1026,7 +1021,7 @@ open_inarch (const char *archive_filename, const char *file)
       output_filename = xstrdup (archive_filename);
 
       /* Create an empty archive.  */
-      arch = bfd_openw (archive_filename, target);
+      arch = bfd_openw (archive_filename, arch_target);
       if (arch == NULL
 	  || ! bfd_set_format (arch, bfd_archive)
 	  || ! bfd_close (arch))
@@ -1035,7 +1030,7 @@ open_inarch (const char *archive_filename, const char *file)
         non_fatal (_("creating %s"), archive_filename);
     }
 
-  arch = bfd_openr (archive_filename, target);
+  arch = bfd_openr (archive_filename, arch_target);
   if (arch == NULL)
     {
     bloser:
@@ -1069,12 +1064,21 @@ open_inarch (const char *archive_filename, const char *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 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);
-  /* Read all the contents right away, regardless.  */
   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;
     }
@@ -1566,8 +1570,9 @@ replace_members (bfd *arch, char **files_to_move, bool quick)
 		    }
 		  else
 		    {
+		      const char *targ = target ? target : plugin_target;
 		      replaced = ar_emul_replace (after_bfd, *files_to_move,
-						  target, verbose);
+						  targ, verbose);
 		    }
 		  if (replaced)
 		    {
@@ -1593,7 +1598,8 @@ replace_members (bfd *arch, char **files_to_move, bool quick)
 	}
       else
         {
-	  changed |= ar_emul_append (after_bfd, *files_to_move, target,
+	  const char *targ = target ? target : plugin_target;
+	  changed |= ar_emul_append (after_bfd, *files_to_move, targ,
 				     verbose, make_thin_archive);
 	}
 
diff --git a/binutils/arsup.c b/binutils/arsup.c
index 67cbd5c2835..e71c860e9e1 100644
--- a/binutils/arsup.c
+++ b/binutils/arsup.c
@@ -32,11 +32,6 @@
 #include "bucomm.h"
 #include "arsup.h"
 
-static void map_over_list
-  (bfd *, void (*function) (bfd *, bfd *), struct list *);
-static void ar_directory_doer (bfd *, bfd *);
-static void ar_addlib_doer (bfd *, bfd *);
-
 extern int verbose;
 extern int deterministic;
 
@@ -46,6 +41,12 @@ static char *temp_name;
 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)
 {
@@ -180,11 +181,7 @@ ar_open (char *name, int t)
 	  bfd *element;
 	  bfd *ibfd;
 
-#if BFD_SUPPORTS_PLUGINS	  
-	  ibfd = bfd_openr (name, "plugin");
-#else
 	  ibfd = bfd_openr (name, NULL);
-#endif
 
 	  if (!ibfd)
 	    {
@@ -206,8 +203,15 @@ ar_open (char *name, int t)
 	  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);
@@ -266,11 +270,7 @@ ar_addmod (struct list *list)
 	{
 	  bfd *abfd;
 
-#if BFD_SUPPORTS_PLUGINS	  
-	  abfd = bfd_openr (list->name, "plugin");
-#else
-	  abfd = bfd_openr (list->name, NULL);
-#endif
+	  abfd = bfd_openr (list->name, plugin_target);
 	  if (!abfd)
 	    {
 	      fprintf (stderr, _("%s: can't open file %s\n"),
@@ -397,7 +397,7 @@ ar_replace (struct list *list)
 	      if (FILENAME_CMP (bfd_get_filename (member), list->name) == 0)
 		{
 		  /* Found the one to replace.  */
-		  bfd *abfd = bfd_openr (list->name, NULL);
+		  bfd *abfd = bfd_openr (list->name, plugin_target);
 
 		  if (!abfd)
 		    {
@@ -421,7 +421,7 @@ ar_replace (struct list *list)
 
 	  if (!found)
 	    {
-	      bfd *abfd = bfd_openr (list->name, NULL);
+	      bfd *abfd = bfd_openr (list->name, plugin_target);
 
 	      fprintf (stderr,_("%s: can't find module file %s\n"),
 		       program_name, list->name);
@@ -504,7 +504,6 @@ ar_extract (struct list *list)
 
 	  if (!found)
 	    {
-	      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 9815e71f2cb..8b41d42f5f0 100644
--- a/binutils/bucomm.h
+++ b/binutils/bucomm.h
@@ -84,4 +84,20 @@ extern int smart_rename (const char *, const char *, int,
   ((*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;
+      /* Arrange for the plugin target to be tried first in
+	 bfd_check_format.  */
+      abfd->target_defaulted = false;
+    }
+}
+
 #endif /* _BUCOMM_H */
diff --git a/binutils/nm.c b/binutils/nm.c
index a7f0e9d9409..130b6e6015e 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -1601,6 +1601,14 @@ display_archive (bfd *file)
   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 (;;)
     {
@@ -1618,6 +1626,8 @@ display_archive (bfd *file)
       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))
 	{


More information about the Binutils-cvs mailing list