]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
archives and plugin target
authorAlan Modra <amodra@gmail.com>
Tue, 12 Aug 2025 13:16:36 +0000 (22:46 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 15 Aug 2025 22:07:08 +0000 (07:37 +0930)
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.

bfd/configure
bfd/configure.ac
bfd/plugin.c
binutils/ar.c
binutils/arsup.c
binutils/bucomm.h
binutils/nm.c

index 28ac5ccfbe570d7454db5ab81d67a4919f207878..4bd81d300ed0ee2a7226ddc4b30bcd5860249892 100755 (executable)
@@ -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
index 502c526b606aaef61bead97db0f5ab83acf0aa1d..144887578745d1a5c769d428fc9994313843452c 100644 (file)
@@ -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")
index 733e7f0f322ec2d801e4b2b22e9913319e1d7c70..2be384d8ef556f5ccdb871daa2f5ce7d0f3efc12 100644 (file)
@@ -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),
index 3cac3f3fb2681287e2101152135fb3a6ddc90e1a..79f40db991ce535b48e5d95d64a3121a0bc5f707 100644 (file)
 #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);
-\f
+
 /** 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);
        }
 
index 67cbd5c2835b8decfb1b77d3b65e00993abd3dd6..e71c860e9e1d1158d17d21d5be2f3f22675ffb91 100644 (file)
 #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);
            }
index 9815e71f2cba283a70e55be1a452b870aaef6cb2..8b41d42f5f068a48cfd679a58c011084d1db0b3f 100644 (file)
@@ -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 */
index a7f0e9d9409fbf3c2a2438da83e46896ed17bd5f..130b6e6015e2866211ad67e49a9f13bfba6d55d6 100644 (file)
@@ -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))
        {