* 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. ---
With (most) nits corrected... see my earlier post for details. Okay to push? ChangeLog | 17 +++++++++++ NEWS | 5 ++- doc/libtool.texi | 7 +++++ libltdl/libltdl/lt__private.h | 1 + libltdl/ltdl.c | 26 ++++++++++++++++- libltdl/ltdl.h | 1 + libltdl/m4/ltdl.m4 | 2 +- tests/lt_dladvise.at | 61 +++++++++++++++++++++++++++++++++------- 8 files changed, 104 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 15ffae1..2a1c843 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-05-06 Gary V. Vaughan <[EMAIL PROTECTED]> + + 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-05-05 Gary V. Vaughan <[EMAIL PROTECTED]> Fix libtoolize test failure with aclocal < 1.10.1 diff --git a/NEWS b/NEWS index 2b113fb..3354e6c 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,10 @@ NEWS - list of user-visible changes between releases of GNU Libtool New in 2.2.??: 2008-06-??: 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. New in 2.2.4: 2008-05-04: git version 2.2.3a, Libtool team: diff --git a/doc/libtool.texi b/doc/libtool.texi index 31ba0c7..21a3695 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -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 [EMAIL PROTECTED] int lt_dladvise_preload (lt_dladvise [EMAIL PROTECTED]) +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}. [EMAIL PROTECTED] 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, diff --git a/libltdl/libltdl/lt__private.h b/libltdl/libltdl/lt__private.h index 4ce936d..f4c4a3d 100644 --- a/libltdl/libltdl/lt__private.h +++ b/libltdl/libltdl/lt__private.h @@ -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 --- */ diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index a89c6bb..5a26565 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -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) diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index bc60b88..8b516ad 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -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); diff --git a/libltdl/m4/ltdl.m4 b/libltdl/m4/ltdl.m4 index 6c277b4..8e5b8ed 100644 --- a/libltdl/m4/ltdl.m4 +++ b/libltdl/m4/ltdl.m4 @@ -264,7 +264,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], diff --git a/tests/lt_dladvise.at b/tests/lt_dladvise.at index 617539f..c0cd768 100644 --- a/tests/lt_dladvise.at +++ b/tests/lt_dladvise.at @@ -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 -- 1.5.4.3
pgp7bNbEdE7Ys.pgp
Description: PGP signature