PR24262, plugin search dir doesn't respect --libdir
authorAlan Modra <amodra@gmail.com>
Thu, 26 Sep 2019 06:50:35 +0000 (16:20 +0930)
committerAlan Modra <amodra@gmail.com>
Thu, 26 Sep 2019 10:21:18 +0000 (19:51 +0930)
bfd/
PR 24262
* Makefile.am (AM_CPPFLAGS): Add -DLIBDIR.
* plugin.c (load_plugin): Search both ${libdir}/bfd-plugins and
${bindir}/../lib/bfd-plugins if different.
* Makefile.in: Regenerate.
ld/
PR 24262
* ld.texi (-plugin): Revert 2019-03-15 change.

bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/plugin.c
ld/ChangeLog
ld/ld.texi

index ac0296482b3247b705443fc6fb399ad563f86a0c..8496cb484f9d06cbb9ef18131017193967a809f0 100644 (file)
@@ -1,3 +1,11 @@
+2019-09-26  Alan Modra  <amodra@gmail.com>
+
+       PR 24262
+       * Makefile.am (AM_CPPFLAGS): Add -DLIBDIR.
+       * plugin.c (load_plugin): Search both ${libdir}/bfd-plugins and
+       ${bindir}/../lib/bfd-plugins if different.
+       * Makefile.in: Regenerate.
+
 2019-09-23  Alan Modra  <amodra@gmail.com>
 
        * elf64-ppc.c (ppc64_elf_check_relocs): Use bfd_link_executable
index f31a7345994d0275169d62a09989781cd637619c..ca868e7c2e8694d22196b8d678246423f55bebd3 100644 (file)
@@ -53,7 +53,7 @@ ZLIBINC = @zlibinc@
 WARN_CFLAGS = @WARN_CFLAGS@
 NO_WERROR = @NO_WERROR@
 AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
-AM_CPPFLAGS = -DBINDIR='"$(bindir)"'
+AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DLIBDIR='"$(libdir)"'
 if PLUGINS
 bfdinclude_HEADERS += $(INCDIR)/plugin-api.h
 LIBDL = @lt_cv_dlopen_libs@
index c1cd3718526e5f854d2da4e38538fa6580b2694a..ec1ce3eb8d752ebf2cebeaa32dd318cf8c37af73 100644 (file)
@@ -479,8 +479,9 @@ libbfd_la_LDFLAGS = $(am__append_1) -release `cat libtool-soversion` \
 ZLIB = @zlibdir@ -lz
 ZLIBINC = @zlibinc@
 AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
-AM_CPPFLAGS = -DBINDIR='"$(bindir)"' @HDEFINES@ @COREFLAG@ @TDEFINES@ \
-       $(CSEARCH) $(CSWITCHES) $(HAVEVECS) @INCINTL@
+AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DLIBDIR='"$(libdir)"' @HDEFINES@ \
+       @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES) $(HAVEVECS) \
+       @INCINTL@ $(am__empty)
 @PLUGINS_TRUE@LIBDL = @lt_cv_dlopen_libs@
 
 # bfd.h goes here, for now
index ca26005055e6419455df126c737f40c1b9702ec1..5f059befb40ecb454bdb74fd8ed95ae197f7bfee 100644 (file)
@@ -367,11 +367,15 @@ register_ld_plugin_object_p (const bfd_target *(*object_p) (bfd *))
 static int
 load_plugin (bfd *abfd)
 {
-  char *plugin_dir;
-  char *p;
-  DIR *d;
-  struct dirent *ent;
+  /* The intent was to search ${libdir}/bfd-plugins for plugins, but
+     unfortunately the original implementation wasn't precisely that
+     when configuring binutils using --libdir.  Search in the proper
+     path first, then the old one for backwards compatibility.  */
+  static const char *path[]
+    = { LIBDIR "/bfd-plugins", BINDIR "/../lib/bfd-plugins" };
+  struct stat last_st;
   int found = 0;
+  unsigned int i;
 
   if (!has_plugin)
     return found;
@@ -382,38 +386,58 @@ load_plugin (bfd *abfd)
   if (plugin_program_name == NULL)
     return found;
 
-  plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL);
-  p = make_relative_prefix (plugin_program_name,
-                           BINDIR,
-                           plugin_dir);
-  free (plugin_dir);
-  plugin_dir = NULL;
-
-  d = opendir (p);
-  if (!d)
-    goto out;
-
-  while ((ent = readdir (d)))
+  /* Try not to search the same dir twice, by looking at st_dev and
+     st_ino for the dir.  If we are on a file system that always sets
+     st_ino to zero or the actual st_ino is zero we might waste some
+     time, but that doesn't matter too much.  */
+  last_st.st_dev = 0;
+  last_st.st_ino = 0;
+  for (i = 0; i < sizeof (path) / sizeof (path[0]); i++)
     {
-      char *full_name;
-      struct stat s;
-      int valid_plugin;
-
-      full_name = concat (p, "/", ent->d_name, NULL);
-      if (stat (full_name, &s) == 0 && S_ISREG (s.st_mode))
-       found = try_load_plugin (full_name, abfd, &valid_plugin);
-      if (has_plugin <= 0)
-       has_plugin = valid_plugin;
-      free (full_name);
+      char *plugin_dir = make_relative_prefix (plugin_program_name,
+                                              BINDIR,
+                                              path[i]);
+      if (plugin_dir)
+       {
+         struct stat st;
+         DIR *d;
+
+         if (stat (plugin_dir, &st) == 0
+             && S_ISDIR (st.st_mode)
+             && !(last_st.st_dev == st.st_dev
+                  && last_st.st_ino == st.st_ino
+                  && st.st_ino != 0)
+             && (d = opendir (plugin_dir)) != NULL)
+           {
+             struct dirent *ent;
+
+             last_st.st_dev = st.st_dev;
+             last_st.st_ino = st.st_ino;
+             while ((ent = readdir (d)) != NULL)
+               {
+                 char *full_name;
+
+                 full_name = concat (plugin_dir, "/", ent->d_name, NULL);
+                 if (stat (full_name, &st) == 0 && S_ISREG (st.st_mode))
+                   {
+                     int valid_plugin;
+
+                     found = try_load_plugin (full_name, abfd, &valid_plugin);
+                     if (has_plugin <= 0)
+                       has_plugin = valid_plugin;
+                   }
+                 free (full_name);
+                 if (found)
+                   break;
+               }
+             closedir (d);
+           }
+         free (plugin_dir);
+       }
       if (found)
        break;
     }
 
- out:
-  free (p);
-  if (d)
-    closedir (d);
-
   return found;
 }
 
index c90a587b3ad0ee845b872c6337afb2acd972b552..24f0ae90cbe94ba0d138f264c5b21706132055bf 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-26  Alan Modra  <amodra@gmail.com>
+
+       PR 24262
+       * ld.texi (-plugin): Revert 2019-03-15 change.
+
 2019-09-25  Alan Modra  <amodra@gmail.com>
 
        * ld.texi (SORT_BY_ALIGNMENT): Reword slightly.
index 95fa6a03485560aa36ba872cefed252e092e3d9e..fcbc335c95e04141570a781285f3f50f6c26dde8 100644 (file)
@@ -855,7 +855,7 @@ Note that the location of the compiler originated plugins is different
 from the place where the @command{ar}, @command{nm} and
 @command{ranlib} programs search for their plugins.  In order for
 those commands to make use of a compiler based plugin it must first be
-copied into the @file{$@{bindir@}/../lib/bfd-plugins} directory.  All gcc
+copied into the @file{$@{libdir@}/bfd-plugins} directory.  All gcc
 based linker plugins are backward compatible, so it is sufficient to
 just copy in the newest one.