]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
Implement lt_dlopening of only preloaded modules.
authorGary V. Vaughan <gary@gnu.org>
Fri, 1 Aug 2008 06:12:29 +0000 (13:12 +0700)
committerGary V. Vaughan <gary@gnu.org>
Fri, 1 Aug 2008 06:12:29 +0000 (13:12 +0700)
* libltdl/m4/ltdl.m4 (LTDL_INIT): Check for a libltdl that
provides lt_dladvise_preopen when deciding if installed libltdl
is 'new enough'.
* libltdl/libltdl/lt__private.h (lt__advise): Add a new
is_preload flag.
* libltdl/ltdl.c (lt_dladvise_preload): New api call to set it.
(try_dlopen): If it is set, and the search of preloaded modules
didn't return a match, don't bother searching the filesystem.
* libltdl/ltdl.h (lt_dladvise_preload): Declare it.
* doc/libtool.texi (Libltdl Interface): Document it.
* tests/lt_dladvise.at: Test it (and incidentally add some test
coverage for `libtool -dlpreopen').
* NEWS: Announce it.

ChangeLog
NEWS
doc/libtool.texi
libltdl/libltdl/lt__private.h
libltdl/ltdl.c
libltdl/ltdl.h
libltdl/m4/ltdl.m4
tests/lt_dladvise.at

index 24509900c2f56d4db8014d01e6b37c5fa86fd485..b71097c304a7945afc3057c7bf74234e464a3283 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2008-08-01  Gary V. Vaughan  <gary@gnu.org>
+
+       Implement lt_dlopening of only preloaded modules.
+       * libltdl/m4/ltdl.m4 (LTDL_INIT): Check for a libltdl that
+       provides lt_dladvise_preopen when deciding if installed libltdl
+       is 'new enough'.
+       * libltdl/libltdl/lt__private.h (lt__advise): Add a new
+       is_preload flag.
+       * libltdl/ltdl.c (lt_dladvise_preload): New api call to set it.
+       (try_dlopen): If it is set, and the search of preloaded modules
+       didn't return a match, don't bother searching the filesystem.
+       * libltdl/ltdl.h (lt_dladvise_preload): Declare it.
+       * doc/libtool.texi (Libltdl Interface): Document it.
+       * tests/lt_dladvise.at: Test it (and incidentally add some test
+       coverage for `libtool -dlpreopen').
+       * NEWS: Announce it.
+
 2008-08-01  Vincent Torri  <doursse@users.sf.net>
 
        Add cegcc (Windows CE/PocketPC) support.
diff --git a/NEWS b/NEWS
index a18237158d554e70453a8a0fc4243a3d9c07dcd6..073c345da0386aa9dad74ba723c8fd07df71b63d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,11 @@
 NEWS - list of user-visible changes between releases of GNU Libtool
 
-New in 2.2.??: 2008-06-??: git version 2.2.5a, Libtool team:
+New in 2.2.??: 2008-08-??: git version 2.2.5a, Libtool team:
 
-* Bug fixes:
+* New features:
 
-  - None yet
+  - New lt_dloadvise_preload() call to set a hint that only preloadeded
+    modules can be opened.
 
 * Changes in supported systems or compilers:
 
index b09cc2ae18364387eb648168126d653c62bb32f5..7b6b3f5750764b57c9458fd52447abac7d0feefa 100644 (file)
@@ -3816,6 +3816,13 @@ On failure, @code{lt_dladvise_resident} returns non-zero and sets an error
 message that can be retrieved with @code{lt_dlerror}.
 @end deftypefun
 
+@deftypefun int lt_dladvise_preload (lt_dladvise *@var{advise})
+Set the @code{preload} hint on @var{advise}.  Passing an @var{advise}
+parameter to @code{lt_dlopenadvise} with this hint set causes it to
+load only preloaded modules, so that if a suitable preloaded module is
+not found, @code{lt_dlopenadvise} will return @code{NULL}.
+@end deftypefun
+
 @deftypefun int lt_dlclose (lt_dlhandle @var{handle})
 Decrement the reference count on the module @var{handle}.
 If it drops to zero and no other module depends on this module,
index 4ce936de26d4684921d5c63cadb7a18d40775e4c..f4c4a3d7e32007b3c79b254413f7b2bec021e2bb 100644 (file)
@@ -126,6 +126,7 @@ struct lt__advise {
                                   subsequently loaded modules.  */
   unsigned int is_symlocal:1;  /* module symbols are only available
                                   locally. */
+  unsigned int try_preload_only:1;/* only preloaded modules will be tried. */
 };
 
 /* --- ERROR HANDLING --- */
index a89c6bb8bb9e7ee990e828c2b64a6cfd034fa8f3..5a2656543c8b6e0cdcd76ebb86c28e50003cb81d 100644 (file)
@@ -1129,6 +1129,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
            lt_dladvise advise)
 {
   const char * saved_error     = 0;
+  char *       archive_name    = 0;
   char *       canonical       = 0;
   char *       base_name       = 0;
   char *       dir             = 0;
@@ -1257,16 +1258,21 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
 
       if (vtable)
        {
+         archive_name = MALLOC (char, LT_STRLEN (name) + 3);
          *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
 
-         if (*phandle == NULL)
+         if ((*phandle == NULL) || (archive_name == NULL))
            {
              ++errors;
              goto cleanup;
            }
          newhandle = *phandle;
 
-         if (tryall_dlopen (&newhandle, attempt, advise, vtable) == 0)
+         /* Preloaded modules are always named according to their old
+            archive name.  */
+         sprintf (archive_name, "%s.a", name);
+
+         if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
            {
              goto register_handle;
            }
@@ -1278,6 +1284,13 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
        }
     }
 
+  /* If we are allowing only preloaded modules, and we didn't find
+     anything yet, give up on the search here.  */
+  if (advise && advise->try_preload_only)
+    {
+      goto cleanup;
+    }
+
   /* Check whether we are opening a libtool module (.la extension).  */
   if (ext && streq (ext, archive_ext))
     {
@@ -1461,6 +1474,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
   if (!canonical)              /* was MEMREASSIGNed */
     FREE (base_name);
   FREE (canonical);
+  FREE (archive_name);
 
   return errors;
 }
@@ -1555,6 +1569,14 @@ lt_dladvise_global (lt_dladvise *padvise)
   return 0;
 }
 
+int
+lt_dladvise_preload (lt_dladvise *padvise)
+{
+  assert (padvise && *padvise);
+  (*padvise)->try_preload_only = 1;
+  return 0;
+}
+
 /* Libtool-1.5.x interface for loading a new module named FILENAME.  */
 lt_dlhandle
 lt_dlopen (const char *filename)
index bc60b882c6985cc4066f2869f2eaf6c6a7cb92ff..8b516ad64c48f74ea6c6bfb33008ff5f62621cec 100644 (file)
@@ -71,6 +71,7 @@ LT_SCOPE int      lt_dladvise_ext      (lt_dladvise *advise);
 LT_SCOPE int       lt_dladvise_resident (lt_dladvise *advise);
 LT_SCOPE int       lt_dladvise_local    (lt_dladvise *advise);
 LT_SCOPE int       lt_dladvise_global   (lt_dladvise *advise);
+LT_SCOPE int       lt_dladvise_preload  (lt_dladvise *advise);
 
 /* Portable libltdl versions of the system dlopen() API. */
 LT_SCOPE lt_dlhandle lt_dlopen         (const char *filename);
index 39089639275771a626908e4479597a18f139ca2a..563889e6b33f47a283927757274b22ec1e7af719 100644 (file)
@@ -248,7 +248,7 @@ if test "x$with_included_ltdl" != xyes; then
   # decide whether there is a useful installed version we can use.
   AC_CHECK_HEADER([ltdl.h],
       [AC_CHECK_DECL([lt_dlinterface_register],
-          [AC_CHECK_LIB([ltdl], [lt_dlinterface_register],
+          [AC_CHECK_LIB([ltdl], [lt_dladvise_preload],
               [with_included_ltdl=no],
               [with_included_ltdl=yes])],
           [with_included_ltdl=yes],
index 617539f85076e94efa5325bb98d794a4ab54c0fb..c0cd768ead311d520762754d200b280e1b16309f 100644 (file)
@@ -190,6 +190,25 @@ hint_global (void)
   lt_dladvise_destroy (&advise);
 }
 
+void
+hint_preload (void)
+{
+  lt_dlhandle handle;
+  lt_dladvise advise;
+
+  if (lt_dladvise_init (&advise) || lt_dladvise_preload (&advise))
+    complain ("error setting advise preload");
+
+  handle = moduleopen ("libpreload.la", advise);
+
+  if (handle)
+    {
+      printf("preload: %d\n", moduletest (handle, "h", "k"));
+    }
+
+  lt_dladvise_destroy (&advise);
+}
+
 int
 main (void)
 {
@@ -205,6 +224,7 @@ main (void)
   hint_resident ();
   hint_local ();
   hint_global ();
+  hint_preload ();
 
   if (lt_dlexit () != 0)
     complain ("error during exit");
@@ -258,11 +278,23 @@ int j = 4;
 #endif
 ]])
 
+AT_DATA([modpreload.c],
+[[#ifdef __cplusplus
+extern "C" {
+#endif
+int h (int x) { return 2 * x; }
+int k = 3;
+#ifdef __cplusplus
+}
+#endif
+]])
+
 AT_DATA([expout],
 [[resident: 2
 local: 3
 global: 4
 depend: 5
+preload: 6
 ]])
 
 : ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
@@ -277,6 +309,7 @@ esac], [], [ignore])
 CPPFLAGS="$LTDLINCL $CPPFLAGS"
 
 dlopenable='resident local global'
+dlpreloadable='preload'
 
 # ------------------------------------------------------------------------- #
 # The depend test makes no sense unless compiled without -no-undefined. By  #
@@ -306,23 +339,29 @@ esac
 LDFLAGS="$LDFLAGS -no-undefined"
 
 $CC $CPPFLAGS $CFLAGS -c main.c
-for name in resident local global; do
+for name in resident local global preload; do
   $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c mod$name.c
   AT_CHECK([$LIBTOOL --mode=link $CC -module $CFLAGS $LDFLAGS -o lib$name.la \
             mod$name.lo -rpath /foo -avoid-version], [], [ignore], [ignore])
 done
 
-# TODO: test -dlpreopen
-for dlopen in -dlopen; do
-
-  modules=
-  for module in $dlopenable; do
-    modules="${modules+$modules }$dlopen lib$module.la"
-  done
+preloaded=
+for module in $dlpreloadable; do
+  preloaded="${preloaded+$preloaded }-dlpreopen lib$module.la"
+done
 
-  AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main main.$OBJEXT $modules $LIBLTDL],
-          [], [ignore], [ignore])
-  LT_AT_NOINST_EXEC_CHECK([./main], [$modules], [], [expout], [])
+modules=
+for module in $dlopenable; do
+  modules="${modules+$modules }-dlopen lib$module.la"
 done
 
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main main.$OBJEXT $preloaded $modules $LIBLTDL],
+        [], [ignore], [ignore])
+
+# Remove loadable libpreload module, so we know it is the preloaded module
+# that is being executed by a successful test invocation:
+$LIBTOOL --mode=clean rm libpreload.la
+
+LT_AT_NOINST_EXEC_CHECK([./main], [$modules], [], [expout], [])
+
 AT_CLEANUP