From: Gary V. Vaughan Date: Tue, 8 May 2007 14:38:50 +0000 (+0000) Subject: Without this patch, lt_dlopen always opens modules with symbol X-Git-Tag: release-2-1b~129 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c823c708c8e5f5fe0e748c4837ff6aa8fabb8cb4;p=thirdparty%2Flibtool.git Without this patch, lt_dlopen always opens modules with symbol visibility set according to the underlying implementation. Here, we add lt_dlopenadvise() to allow callers to request, among other things, local or global symbol visibility from the underlying dlloader: * libltdl/ltdl.c (LT_DLRESIDENT_FLAG): Removed. (LT_DLIS_RESIDENT): Use public is_resident info field. (LT_DLIS_SYMLOCAL, LT_DLIS_SYMGLOBAL): New macros to test for module symbol visibility status. (tryall_dlopen): If vtable->module_open() was able to act on either is_symlocal or is_symglobal hints, store that in the handle flags. (lt_dlopenadvise): New function that works like lt_dlopen(), but accepts an advise type to determine whether to ask dlloaders to change default symbol visibility. (lt_dlopen, lt_dlopenext): Just call lt_dlopenadvise() with the correct parameters. (lt_dladvise_init, lt_dladvise_destroy): New functions to initialize and destroy an advise type hint. (lt_dladvise_ext, lt_dladvise_resident, lt_dladvise_local) (lt_dladvise_global): Set hints on an advise type. (openadvise): Factored out of lt_dlopenadvise. (has_library_ext): Factored out of lt_dlopenadvise. * libltdl/ltdl.h: Declare all of the above. (lt_dlinfo): New fields for advise hints. * libltdl/libltdl/lt_dlloader.h (lt_module_open): Add a new advise parameter. Adjust all callers. (lt_dladvise): New opaque type for advise hints. * libltdl/libltdl/lt__private.h (lt__advise): Declare contents of opaque lt_dladvise type. * libltdl/libltdl/lt_error.h (CONFLICTING_FLAGS): New error for attempts to have local and global symbol visibility at the same time. * libltdl/loaders/dld_link.c, libltdl/loaders/dyld.c, libltdl/loaders/load_add_on.c, libltdl/loaders/loadlibrary.c, libltdl/loaders/preopen.c, libltdl/loaders/shl_load.c: Adjust. * libltdl/loaders/dlopen.c (RTLD_LOCAL, RTLD_GLOBAL): Try to define these symbols if the system has equivalents. (vmopen): If unable to act on a caller request to set symbol visibility, then unset the relevant hints in the advise type. * tests/lt_dladvise.at: New tests for the above. * doc/libtool.texi (Libltdl Interface): Updated. * NEWS: Updated. --- diff --git a/ChangeLog b/ChangeLog index ab7cac970..0ebab8069 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +2007-05-08 Gary V. Vaughan + + Without this patch, lt_dlopen always opens modules with symbol + visibility set according to the underlying implementation. + Here, we add lt_dlopenadvise() to allow callers to request, + among other things, local or global symbol visibility from the + underlying dlloader: + + * libltdl/ltdl.c (LT_DLRESIDENT_FLAG): Removed. + (LT_DLIS_RESIDENT): Use public is_resident info field. + (LT_DLIS_SYMLOCAL, LT_DLIS_SYMGLOBAL): New macros to test for + module symbol visibility status. + (tryall_dlopen): If vtable->module_open() was able to act on + either is_symlocal or is_symglobal hints, store that in + the handle flags. + (lt_dlopenadvise): New function that works like lt_dlopen(), + but accepts an advise type to determine whether to ask + dlloaders to change default symbol visibility. + (lt_dlopen, lt_dlopenext): Just call lt_dlopenadvise() with + the correct parameters. + (lt_dladvise_init, lt_dladvise_destroy): New functions to + initialize and destroy an advise type hint. + (lt_dladvise_ext, lt_dladvise_resident, lt_dladvise_local) + (lt_dladvise_global): Set hints on an advise type. + (openadvise): Factored out of lt_dlopenadvise. + (has_library_ext): Factored out of lt_dlopenadvise. + * libltdl/ltdl.h: Declare all of the above. + (lt_dlinfo): New fields for advise hints. + * libltdl/libltdl/lt_dlloader.h (lt_module_open): Add a new + advise parameter. Adjust all callers. + (lt_dladvise): New opaque type for advise hints. + * libltdl/libltdl/lt__private.h (lt__advise): Declare + contents of opaque lt_dladvise type. + * libltdl/libltdl/lt_error.h (CONFLICTING_FLAGS): New error + for attempts to have local and global symbol visibility at the + same time. + * libltdl/loaders/dld_link.c, libltdl/loaders/dyld.c, + libltdl/loaders/load_add_on.c, libltdl/loaders/loadlibrary.c, + libltdl/loaders/preopen.c, libltdl/loaders/shl_load.c: Adjust. + * libltdl/loaders/dlopen.c (RTLD_LOCAL, RTLD_GLOBAL): Try to + define these symbols if the system has equivalents. + (vmopen): If unable to act on a caller request to set symbol + visibility, then unset the relevant hints in the advise type. + * tests/lt_dladvise.at: New tests for the above. + * doc/libtool.texi (Libltdl Interface): Updated. + * NEWS: Updated. + 2007-05-03 Ralf Wildenhues * libltdl/config/ltmain.m4sh (func_mode_link): When adding diff --git a/Makefile.am b/Makefile.am index bf61fab67..3d086eed5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -445,6 +445,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/old-m4-iface.at \ tests/am-subdir.at \ tests/lt_dlexit.at \ + tests/lt_dladvise.at \ tests/standalone.at \ tests/subproject.at \ tests/nonrecursive.at \ diff --git a/NEWS b/NEWS index 6c0d5d591..8792f6360 100644 --- a/NEWS +++ b/NEWS @@ -8,10 +8,6 @@ New in 2.1a: 2007-??-??; CVS version 2.1a, Libtool team: libltdl currently does not build. The new structure of libltdl with preopened modules exposes some long-lived bugs here. - - Since libltdl does not use the RTLD_GLOBAL global flag with dlopen - any more, some setups may fail. A mechanism to allow the user to - choose the mode has not been implemented yet. - * Important incompatible changes and obsoleted features: - Removed deprecated APIs from libltdl: lt_dlcaller_register, @@ -54,6 +50,14 @@ New in 2.1a: 2007-??-??; CVS version 2.1a, Libtool team: lt_dlhandle_iterate, lt_dlhandle_fetch, lt_dlhandle_map. - New lt_dlinterface_register to maintain separation of concerns between modules loaded by different libraries. + - New lt_dlopenadvise takes a new lt_dladvise type argument, which + lets the caller request local or global symbol visibility from the + module loader with lt_dladvise_local and lt_dladvise_global + respectively. If neither is given, or if lt_dlopen (or lt_dlopenext) + are called, then the system default module symbol visibility is used. + - The new lt_dladvise_init/lt_dladvise_destroy based APIs also allow + caller requests for a filename extension search with lt_dladvise_ext, + and for marking a module unloadable with lt_dladvise_resident. - Allow shell special characters like `$' in source file names, but not in object names, to enhance GCJ support. - An entire new Autotest-based testsuite in addition to the old one. diff --git a/doc/libtool.texi b/doc/libtool.texi index 877209308..8b6d3e906 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -222,8 +222,8 @@ Platform quirks In the past, if a source code package developer wanted to take advantage of the power of shared libraries, he needed to write custom support code for each platform on which his package ran. He also had to design a -configuration interface so that the package installer could choose what sort of -libraries were built. +configuration interface so that the package installer could choose what +sort of libraries were built. @sc{gnu} Libtool simplifies the developer's job by encapsulating both the platform-specific dependencies, and the user interface, in a single @@ -3590,6 +3590,12 @@ The following types are defined in @file{ltdl.h}: Every lt_dlopened module has a handle associated with it. @end deftp +@deftp {Type} lt_dladvise +@code{lt_dladvise} is used to control optional module loading modes. +If it is not used, the default mode of the underlying system module +loader is used. +@end deftp + @deftp {Type} lt_dlsymlist @code{lt_dlsymlist} is a symbol list for dlpreopened modules. This structure is described in @pxref{Dlpreopening}. @@ -3679,6 +3685,99 @@ to be able to @code{dlopen} such libraries as well as libtool modules transparently. @end deftypefun +@deftypefun int lt_dladvise_init (lt_dladvise *@var{advise}) +The @var{advise} parameter can be used to pass hints to the module +loader when using @code{lt_dlopenadvise} to perform the loading. +The @var{advise} parameter needs to be initialised by this function +before it can be used. Any memory used by @var{advise} needs to be +recycled with @code{lt_dladvise_destroy} when it is no longer needed. + +On failure, @code{lt_dladvise_init} returns non-zero and sets an error +message that can be retrieved with @code{lt_dlerror}. +@end deftypefun + +@deftypefun int lt_dladvise_destroy (lt_dladvise *@var{advise}) +Recycle the memory used by @var{advise}. For an example, see the +documentation for @code{lt_dladvise_ext}. + +On failure, @code{lt_dladvise_destroy} returns non-zero and sets an error +message that can be retrieved with @code{lt_dlerror}. +@end deftypefun + +@deftypefun int lt_dladvise_ext (lt_dladvise *@var{advise}) +Set the @code{ext} hint on @var{advise}. Passing an @var{advise} +parameter to @code{lt_dlopenadvise} with this hint set causes it to +try to append different file name extensions like @code{lt_dlopenext}. + +The following example is equivalent to calling +@code{lt_dlopenext (filename)}: + +@example +lt_dlhandle +my_dlopenext (const char *filename) +@{ + lt_dlhandle handle = 0; + lt_dladvise advise; + + if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise)) + handle = lt_dlopenadvise (filename, &advise); + + lt_dladvise_destroy (&advise); + + return handle; +@} +@end example + +On failure, @code{lt_dladvise_ext} returns non-zero and sets an error +message that can be retrieved with @code{lt_dlerror}. +@end deftypefun + +@deftypefun int lt_dladvise_global (lt_dladvise *@var{advise}) +Set the @code{symglobal} hint on @var{advise}. Passing an @var{advise} +parameter to @code{lt_dlopenadvise} with this hint set causes it to try +to make the loaded module's symbols globally available for resolving +unresolved symbols in subsequently loaded modules. + +If neither the @code{symglobal} nor the @code{symlocal} hints are set, +or if a module is loaded without using the @code{lt_dlopenadvise} call +in any case, then the visibility of the module's symbols will be as per +the default for the underlying module loader and @sc{os}. Even if a +suitable hint is passed, not all loaders are able to act upon it in +which case @code{lt_dlgetinfo} will reveal whether the hint was actually +followed. + +On failure, @code{lt_dladvise_global} returns non-zero and sets an error +message that can be retrieved with @code{lt_dlerror}. +@end deftypefun + +@deftypefun int lt_dladvise_local (lt_dladvise *@var{advise}) +Set the @code{symlocal} hint on @var{advise}. Passing an @var{advise} +parameter to @code{lt_dlopenadvise} with this hint set causes it to try +to keep the loaded module's symbols hidden so that they are not +visible to subsequently loaded modules. + +If neither the @code{symglobal} nor the @code{symlocal} hints are set, +or if a module is loaded without using the @code{lt_dlopenadvise} call +in any case, then the visibility of the module's symbols will be as per +the default for the underlying module loader and @sc{os}. Even if a +suitable hint is passed, not all loaders are able to act upon it in +which case @code{lt_dlgetinfo} will reveal whether the hint was actually +followed. + +On failure, @code{lt_dladvise_local} returns non-zero and sets an error +message that can be retrieved with @code{lt_dlerror}. +@end deftypefun + +@deftypefun int lt_dladvise_resident (lt_dladvise *@var{advise}) +Set the @code{resident} hint on @var{advise}. Passing an @var{advise} +parameter to @code{lt_dlopenadvise} with this hint set causes it to try +to make the loaded module resident in memory, so that it cannot be +unloaded with a later call to @code{lt_dlclose}. + +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_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, @@ -3853,17 +3952,16 @@ Some of the internal information about each loaded module that is maintained by libltdl is available to the user, in the form of this structure: -@deftypefn {Type} {struct} lt_dlinfo @{ @w{char *@var{filename};} @w{char *@var{name};} @w{int @var{ref_count};} @w{lt_module @var{module};}@} +@deftypefn {Type} {struct} lt_dlinfo @{ @w{char *@var{filename};} @w{char *@var{name};} @w{int @var{ref_count};} @w{int @var{is_resident};} @w{int @var{is_symglobal};} @w{int @var{is_symlocal};}@} @code{lt_dlinfo} is used to store information about a module. The @var{filename} attribute is a null-terminated character string of the real module file name. If the module is a libtool module then @var{name} is its module name (e.g.@: @code{"libfoo"} for @code{"dir/libfoo.la"}), otherwise it is set to @code{NULL}. The @var{ref_count} attribute is a reference counter that describes how -often the same module is currently loaded. @var{module} is the -dlloader's internal handle for the native module, and can be used, for -example, by a loader to check whether @var{module} has already been -loaded to save loading it again. +often the same module is currently loaded. The remaining fields can +be compared to any hints that were passed to @code{lt_dlopenadvise} +to determine whether the underlying loader was able to follow them. @end deftypefn The following function will return a pointer to libltdl's internal copy diff --git a/libltdl/libltdl/lt__private.h b/libltdl/libltdl/lt__private.h index 5c21b15ae..c258df8e1 100644 --- a/libltdl/libltdl/lt__private.h +++ b/libltdl/libltdl/lt__private.h @@ -121,7 +121,16 @@ struct lt__handle { int flags; /* various boolean stats */ }; - +typedef struct lt__advise lt__advise; + +struct lt__advise { + unsigned int try_ext:1; /* try system library extensions. */ + unsigned int is_resident:1; /* module can't be unloaded. */ + unsigned int is_symglobal:1; /* module symbols can satisfy + subsequently loaded modules. */ + unsigned int is_symlocal:1; /* module symbols are only available + locally. */ +}; /* --- ERROR HANDLING --- */ diff --git a/libltdl/libltdl/lt_dlloader.h b/libltdl/libltdl/lt_dlloader.h index 3cff1b68d..46c8b4db3 100644 --- a/libltdl/libltdl/lt_dlloader.h +++ b/libltdl/libltdl/lt_dlloader.h @@ -1,6 +1,6 @@ /* lt_dlloader.h -- dynamic library loader interface - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2007 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the @@ -38,10 +38,12 @@ LT_BEGIN_C_DECLS typedef void * lt_dlloader; typedef void * lt_module; typedef void * lt_user_data; +typedef void * lt_dladvise; /* Function pointer types for module loader vtable entries: */ typedef lt_module lt_module_open (lt_user_data data, - const char *filename); + const char *filename, + lt_dladvise advise); typedef int lt_module_close (lt_user_data data, lt_module module); typedef void * lt_find_sym (lt_user_data data, lt_module module, diff --git a/libltdl/libltdl/lt_error.h b/libltdl/libltdl/lt_error.h index 68b94f5b7..dbb462dbf 100644 --- a/libltdl/libltdl/lt_error.h +++ b/libltdl/libltdl/lt_error.h @@ -60,7 +60,8 @@ LT_BEGIN_C_DECLS LT_ERROR(SHUTDOWN, "library already shutdown\0") \ LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module\0") \ LT_ERROR(INVALID_MUTEX_ARGS, "internal error (code withdrawn)\0")\ - LT_ERROR(INVALID_POSITION, "invalid search path insert position\0") + LT_ERROR(INVALID_POSITION, "invalid search path insert position\0")\ + LT_ERROR(CONFLICTING_FLAGS, "symbol visibility can be global or local\0") /* Enumerate the symbolic error names. */ enum { diff --git a/libltdl/loaders/dld_link.c b/libltdl/loaders/dld_link.c index e4370abcd..189ee3b09 100644 --- a/libltdl/loaders/dld_link.c +++ b/libltdl/loaders/dld_link.c @@ -1,6 +1,7 @@ /* loader-dld_link.c -- dynamic linking with dld - Copyright (C) 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -44,7 +45,8 @@ LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ -static lt_module vm_open (lt_user_data loader_data, const char *filename); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); @@ -94,7 +96,8 @@ get_vtable (lt_user_data loader_data) loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module -vm_open (lt_user_data LT__UNUSED loader_data, const char *filename) +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) { lt_module module = lt__strdup (filename); diff --git a/libltdl/loaders/dlopen.c b/libltdl/loaders/dlopen.c index c3711af96..5313bc795 100644 --- a/libltdl/loaders/dlopen.c +++ b/libltdl/loaders/dlopen.c @@ -1,6 +1,7 @@ /* loader-dlopen.c -- dynamic linking with dlopen/dlsym - Copyright (C) 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -44,7 +45,8 @@ LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ -static lt_module vm_open (lt_user_data loader_data, const char *filename); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); @@ -122,6 +124,19 @@ get_vtable (lt_user_data loader_data) # define LT_LAZY_OR_NOW 0 #endif /* !LT_LAZY_OR_NOW */ +/* We only support local and global symbols from modules for loaders + that provide such a thing, otherwise the system default is used. */ +#if !defined(RTLD_GLOBAL) +# if defined(DL_GLOBAL) +# define RTLD_GLOBAL DL_GLOBAL +# endif +#endif /* !RTLD_GLOBAL */ +#if !defined(RTLD_LOCAL) +# if defined(DL_LOCAL) +# define RTLD_LOCAL DL_LOCAL +# endif +#endif /* !RTLD_LOCAL */ + #if defined(HAVE_DLERROR) # define DLERROR(arg) dlerror () #else @@ -135,9 +150,35 @@ get_vtable (lt_user_data loader_data) loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module -vm_open (lt_user_data LT__UNUSED loader_data, const char *filename) +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise advise) { - lt_module module = dlopen (filename, LT_LAZY_OR_NOW); + int module_flags = LT_LAZY_OR_NOW; + lt_module module; + + if (advise) + { +#ifdef RTLD_GLOBAL + /* If there is some means of asking for global symbol resolution, + do so. */ + if (((lt__advise *) advise)->is_symglobal) + module_flags |= RTLD_GLOBAL; +#else + /* Otherwise, reset that bit so the caller can tell it wasn't + acted on. */ + ((lt__advise *) advise)->is_symglobal = 0; +#endif + +/* And similarly for local only symbol resolution. */ +#ifdef RTLD_LOCAL + if (((lt__advise *) advise)->is_symlocal) + module_flags |= RTLD_LOCAL; +#else + ((lt__advise *) advise)->is_symlocal = 0; +#endif + } + + module = dlopen (filename, module_flags); if (!module) { diff --git a/libltdl/loaders/dyld.c b/libltdl/loaders/dyld.c index 6b9fc8722..216b42602 100644 --- a/libltdl/loaders/dyld.c +++ b/libltdl/loaders/dyld.c @@ -1,6 +1,7 @@ /* loader-dyld.c -- dynamic linking on darwin and OS X - Copyright (C) 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007 Free Software Foundation, Inc. Written by Peter O'Gorman, 1998 NOTE: The canonical source of this file is maintained with the @@ -46,7 +47,8 @@ LT_END_C_DECLS libltdl's loader list: */ static int vl_init (lt_user_data loader_data); static int vl_exit (lt_user_data loader_data); -static lt_module vm_open (lt_user_data loader_data, const char *filename); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); @@ -213,7 +215,8 @@ vl_init (lt_user_data loader_data) loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module -vm_open (lt_user_data loader_data, const char *filename) +vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) { lt_module module = 0; NSObjectFileImage ofi = 0; diff --git a/libltdl/loaders/load_add_on.c b/libltdl/loaders/load_add_on.c index 9b2f3afdd..f79604ff2 100644 --- a/libltdl/loaders/load_add_on.c +++ b/libltdl/loaders/load_add_on.c @@ -1,6 +1,7 @@ /* loader-load_add_on.c -- dynamic linking for BeOS - Copyright (C) 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -44,7 +45,8 @@ LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ -static lt_module vm_open (lt_user_data loader_data, const char *filename); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); @@ -92,7 +94,8 @@ get_vtable (lt_user_data loader_data) loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module -vm_open (lt_user_data LT__UNUSED loader_data, const char *filename) +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) { image_id image = 0; diff --git a/libltdl/loaders/loadlibrary.c b/libltdl/loaders/loadlibrary.c index 4d77ec170..71f90c718 100644 --- a/libltdl/loaders/loadlibrary.c +++ b/libltdl/loaders/loadlibrary.c @@ -1,7 +1,7 @@ /* loader-loadlibrary.c -- dynamic linking for Win32 - Copyright (C) 1998, 1999, 2000, 2004, 2005, - 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -49,7 +49,8 @@ LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ -static lt_module vm_open (lt_user_data loader_data, const char *filename); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); @@ -100,7 +101,8 @@ get_vtable (lt_user_data loader_data) loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module -vm_open (lt_user_data LT__UNUSED loader_data, const char *filename) +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) { lt_module module = 0; char *ext; diff --git a/libltdl/loaders/preopen.c b/libltdl/loaders/preopen.c index 4497d6813..82066fec6 100644 --- a/libltdl/loaders/preopen.c +++ b/libltdl/loaders/preopen.c @@ -1,6 +1,7 @@ /* loader-preopen.c -- emulate dynamic linking using preloaded_symbols - Copyright (C) 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -46,7 +47,8 @@ LT_END_C_DECLS libltdl's loader list: */ static int vl_init (lt_user_data loader_data); static int vl_exit (lt_user_data loader_data); -static lt_module vm_open (lt_user_data loader_data, const char *filename); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); @@ -139,7 +141,8 @@ vl_exit (lt_user_data LT__UNUSED loader_data) loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module -vm_open (lt_user_data LT__UNUSED loader_data, const char *filename) +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) { symlist_chain *lists; lt_module module = 0; diff --git a/libltdl/loaders/shl_load.c b/libltdl/loaders/shl_load.c index 2d8844ee8..15f00bdff 100644 --- a/libltdl/loaders/shl_load.c +++ b/libltdl/loaders/shl_load.c @@ -1,6 +1,7 @@ /* loader-shl_load.c -- dynamic linking with shl_load (HP-UX) - Copyright (C) 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2006, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -44,7 +45,8 @@ LT_END_C_DECLS /* Boilerplate code to set up the vtable for hooking this loader into libltdl's loader list: */ -static lt_module vm_open (lt_user_data loader_data, const char *filename); +static lt_module vm_open (lt_user_data loader_data, const char *filename, + lt_dladvise advise); static int vm_close (lt_user_data loader_data, lt_module module); static void * vm_sym (lt_user_data loader_data, lt_module module, const char *symbolname); @@ -135,7 +137,8 @@ get_vtable (lt_user_data loader_data) loader. Returns an opaque representation of the newly opened module for processing with this loader's other vtable functions. */ static lt_module -vm_open (lt_user_data LT__UNUSED loader_data, const char *filename) +vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, + lt_dladvise LT__UNUSED advise) { static shl_t self = (shl_t) 0; lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index 7aced2bb9..79769cc3b 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -1,7 +1,7 @@ /* ltdl.c -- system independent dlopen wrapper - Copyright (C) 1998, 1999, 2000, 2004, 2005, - 2006 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -58,16 +58,11 @@ or obtained by writing to the Free Software Foundation, Inc., #undef LT_SYMBOL_OVERHEAD #define LT_SYMBOL_OVERHEAD 5 - /* Various boolean flags can be stored in the flags field of an lt_dlhandle... */ -#define LT_DLGET_FLAG(handle, flag) ((((lt__handle *) handle)->flags & (flag)) == (flag)) -#define LT_DLSET_FLAG(handle, flag) (((lt__handle *)handle)->flags |= (flag)) - -#define LT_DLRESIDENT_FLAG (0x01 << 0) -/* ...add more flags here... */ - -#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) +#define LT_DLIS_RESIDENT(handle) (((lt__handle*)handle)->info.is_resident) +#define LT_DLIS_SYMGLOBAL(handle) (((lt__handle*)handle)->info.is_symglobal) +#define LT_DLIS_SYMLOCAL(handle) (((lt__handle*)handle)->info.is_symlocal) static const char objdir[] = LT_OBJDIR; @@ -91,11 +86,11 @@ typedef int foreach_callback_func (char *filename, void *data1, /* foreachfile_callback itself calls a function of this type: */ typedef int file_worker_func (const char *filename, void *data); + static int foreach_dirinpath (const char *search_path, const char *base_name, foreach_callback_func *func, void *data1, void *data2); - static int find_file_callback (char *filename, void *data1, void *data2); static int find_handle_callback (char *filename, void *data, @@ -111,17 +106,23 @@ static FILE *find_file (const char *search_path, const char *base_name, char **pdir); static lt_dlhandle *find_handle (const char *search_path, const char *base_name, - lt_dlhandle *handle); + lt_dlhandle *handle, + lt_dladvise advise); static int find_module (lt_dlhandle *handle, const char *dir, const char *libdir, const char *dlname, - const char *old_name, int installed); + const char *old_name, int installed, + lt_dladvise advise); +static int has_library_ext (const char *filename); static int load_deplibs (lt_dlhandle handle, char *deplibs); static int trim (char **dest, const char *str); static int try_dlopen (lt_dlhandle *handle, - const char *filename); + const char *filename, const char *ext, + lt_dladvise advise); static int tryall_dlopen (lt_dlhandle *handle, - const char *filename); + const char *filename, + lt_dladvise advise); static int unload_deplibs (lt_dlhandle handle); +static lt__advise *advise_dup (lt__advise *advise); static int lt_argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry); static int lt_argz_insertinorder (char **pargz, size_t *pargz_len, @@ -330,8 +331,13 @@ lt_dlexit (void) return errors; } + +/* Try all dlloaders for FILENAME. If the library is not successfully + loaded, return non-zero. Otherwise, the dlhandle is stored at the + address given in PHANDLE. */ static int -tryall_dlopen (lt_dlhandle *phandle, const char *filename) +tryall_dlopen (lt_dlhandle *phandle, const char *filename, + lt_dladvise advise) { lt__handle * handle = (lt__handle *) handles; const char * saved_error = 0; @@ -390,14 +396,27 @@ tryall_dlopen (lt_dlhandle *phandle, const char *filename) while ((loader = (lt_dlloader *) lt_dlloader_next (loader))) { + lt__advise *advise_taken = 0; + + if (advise) + advise_taken = advise_dup (advise); + vtable = lt_dlloader_get (loader); handle->module = (*vtable->module_open) (vtable->dlloader_data, - filename); + filename, advise_taken); if (handle->module != 0) { + if (advise_taken) + { + handle->info.is_resident = advise_taken->is_resident; + handle->info.is_symglobal = advise_taken->is_symglobal; + handle->info.is_symlocal = advise_taken->is_symlocal; + } break; } + + FREE (advise_taken); } if (!loader) @@ -419,7 +438,8 @@ tryall_dlopen (lt_dlhandle *phandle, const char *filename) static int tryall_dlopen_module (lt_dlhandle *handle, const char *prefix, - const char *dirname, const char *dlname) + const char *dirname, const char *dlname, + lt_dladvise advise) { int error = 0; char *filename = 0; @@ -453,10 +473,10 @@ tryall_dlopen_module (lt_dlhandle *handle, const char *prefix, shuffled. Otherwise, attempt to open FILENAME as a module. */ if (prefix) { - error += tryall_dlopen_module (handle, - (const char *) 0, prefix, filename); + error += tryall_dlopen_module (handle, (const char *) 0, + prefix, filename, advise); } - else if (tryall_dlopen (handle, filename) != 0) + else if (tryall_dlopen (handle, filename, advise) != 0) { ++error; } @@ -467,12 +487,13 @@ tryall_dlopen_module (lt_dlhandle *handle, const char *prefix, static int find_module (lt_dlhandle *handle, const char *dir, const char *libdir, - const char *dlname, const char *old_name, int installed) + const char *dlname, const char *old_name, int installed, + lt_dladvise advise) { /* Try to open the old library first; if it was dlpreopened, we want the preopened version of it, even if a dlopenable module is available. */ - if (old_name && tryall_dlopen (handle, old_name) == 0) + if (old_name && tryall_dlopen (handle, old_name, advise) == 0) { return 0; } @@ -483,22 +504,23 @@ find_module (lt_dlhandle *handle, const char *dir, const char *libdir, /* try to open the installed module */ if (installed && libdir) { - if (tryall_dlopen_module (handle, - (const char *) 0, libdir, dlname) == 0) + if (tryall_dlopen_module (handle, (const char *) 0, + libdir, dlname, advise) == 0) return 0; } /* try to open the not-installed module */ if (!installed) { - if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) + if (tryall_dlopen_module (handle, dir, objdir, + dlname, advise) == 0) return 0; } /* maybe it was moved to another directory */ { - if (dir && (tryall_dlopen_module (handle, - (const char *) 0, dir, dlname) == 0)) + if (dir && (tryall_dlopen_module (handle, (const char *) 0, + dir, dlname, advise) == 0)) return 0; } } @@ -703,10 +725,11 @@ find_file (const char *search_path, const char *base_name, char **pdir) } static int -find_handle_callback (char *filename, void *data, void * LT__UNUSED ignored) +find_handle_callback (char *filename, void *data, void *data2) { lt_dlhandle *handle = (lt_dlhandle *) data; int notfound = access (filename, R_OK); + lt_dladvise advise = (lt_dladvise) data2; /* Bail out if file cannot be read... */ if (notfound) @@ -714,7 +737,7 @@ find_handle_callback (char *filename, void *data, void * LT__UNUSED ignored) /* Try to dlopen the file, but do not continue searching in any case. */ - if (tryall_dlopen (handle, filename) != 0) + if (tryall_dlopen (handle, filename, advise) != 0) *handle = 0; return 1; @@ -724,13 +747,13 @@ find_handle_callback (char *filename, void *data, void * LT__UNUSED ignored) found but could not be opened, *HANDLE will be set to 0. */ static lt_dlhandle * find_handle (const char *search_path, const char *base_name, - lt_dlhandle *handle) + lt_dlhandle *handle, lt_dladvise advise) { if (!search_path) return 0; if (!foreach_dirinpath (search_path, base_name, find_handle_callback, - handle, 0)) + handle, advise)) return 0; return handle; @@ -1066,16 +1089,18 @@ cleanup: return errors; } + /* Try to open FILENAME as a module. */ static int -try_dlopen (lt_dlhandle *phandle, const char *filename) +try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext, + lt_dladvise advise) { - const char * ext = 0; const char * saved_error = 0; char * canonical = 0; char * base_name = 0; char * dir = 0; char * name = 0; + char * try = 0; int errors = 0; lt_dlhandle newhandle; @@ -1094,9 +1119,9 @@ try_dlopen (lt_dlhandle *phandle, const char *filename) newhandle = *phandle; /* lt_dlclose()ing yourself is very bad! Disallow it. */ - LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); + ((lt__handle *) newhandle)->info.is_resident = 1; - if (tryall_dlopen (&newhandle, 0) != 0) + if (tryall_dlopen (&newhandle, 0, advise) != 0) { FREE (*phandle); return 1; @@ -1107,9 +1132,24 @@ try_dlopen (lt_dlhandle *phandle, const char *filename) assert (filename && *filename); + if (ext) + { + try = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1); + if (!try) + return 1; + + sprintf(try, "%s%s", filename, ext); + } + else + { + try = lt__strdup (filename); + if (!try) + return 1; + } + /* Doing this immediately allows internal functions to safely assume only canonicalized paths are passed. */ - if (canonicalize_path (filename, &canonical) != 0) + if (canonicalize_path (try, &canonical) != 0) { ++errors; goto cleanup; @@ -1139,11 +1179,11 @@ try_dlopen (lt_dlhandle *phandle, const char *filename) assert (base_name && *base_name); - ext = strrchr (base_name, '.'); if (!ext) { ext = base_name + LT_STRLEN (base_name); } + ext = strrchr (base_name, '.'); /* extract the module name from the file name */ name = MALLOC (char, ext - base_name + 1); @@ -1262,7 +1302,8 @@ try_dlopen (lt_dlhandle *phandle, const char *filename) { newhandle = *phandle; /* find_module may replace newhandle */ - if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) + if (find_module (&newhandle, dir, libdir, dlname, old_name, + installed, advise)) { unload_deplibs (*phandle); ++errors; @@ -1305,19 +1346,21 @@ try_dlopen (lt_dlhandle *phandle, const char *filename) first in user_search_path and then other prescribed paths. Otherwise (or in any case if the module was not yet found) try opening just the module name as passed. */ - if ((dir || (!find_handle (user_search_path, base_name, &newhandle) + if ((dir || (!find_handle (user_search_path, base_name, + &newhandle, advise) && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, - &newhandle) + &newhandle, advise) #if defined(LT_MODULE_PATH_VAR) && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name, - &newhandle) + &newhandle, advise) #endif #if defined(LT_DLSEARCH_PATH) - && !find_handle (sys_dlsearch_path, base_name, &newhandle) + && !find_handle (sys_dlsearch_path, base_name, + &newhandle, advise) #endif ))) { - if (tryall_dlopen (&newhandle, filename) != 0) + if (tryall_dlopen (&newhandle, filename, advise) != 0) { newhandle = NULL; } @@ -1347,6 +1390,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename) cleanup: FREE (dir); + FREE (try); FREE (name); if (!canonical) /* was MEMREASSIGNed */ FREE (base_name); @@ -1355,18 +1399,6 @@ try_dlopen (lt_dlhandle *phandle, const char *filename) return errors; } -lt_dlhandle -lt_dlopen (const char *filename) -{ - lt_dlhandle handle = 0; - - /* Just incase we missed a code path in try_dlopen() that reports - an error, but forgets to reset handle... */ - if (try_dlopen (&handle, filename) != 0) - return 0; - - return handle; -} /* If the last error messge store was `FILE_NOT_FOUND', then return non-zero. */ @@ -1382,92 +1414,172 @@ file_not_found (void) return 0; } -/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to - open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, - and if a file is still not found try again with MODULE_EXT appended - instead. */ -lt_dlhandle -lt_dlopenext (const char *filename) -{ - lt_dlhandle handle = 0; - char * tmp = 0; - char * ext = 0; - size_t len; - int errors = 0; - if (!filename) - { - return lt_dlopen (filename); - } +/* Unless FILENAME already bears a suitable library extension, then + return 0. */ +static int +has_library_ext (const char *filename) +{ + char * ext = 0; + size_t len; assert (filename); len = LT_STRLEN (filename); ext = strrchr (filename, '.'); - /* If FILENAME already bears a suitable extension, there is no need - to try appending additional extensions. */ if (ext && ((streq (ext, archive_ext)) #if defined(LT_MODULE_EXT) - || (streq (ext, shlib_ext)) + || (streq (ext, shlib_ext)) #endif - )) + )) { - return lt_dlopen (filename); + return 1; } - /* First try appending ARCHIVE_EXT. */ - tmp = MALLOC (char, len + LT_STRLEN (archive_ext) + 1); - if (!tmp) - return 0; + return 0; +} + + +/* Initialise and configure a user lt_dladvise opaque object. */ + +int +lt_dladvise_init (lt_dladvise *padvise) +{ + lt__advise *advise = (lt__advise *) lt__zalloc (sizeof (lt__advise)); + *padvise = advise; + return (advise ? 0 : 1); +} + +int +lt_dladvise_destroy (lt_dladvise *padvise) +{ + if (padvise) + FREE(*padvise); + return 0; +} - strcpy (tmp, filename); - strcat (tmp, archive_ext); - errors = try_dlopen (&handle, tmp); +int +lt_dladvise_ext (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + ((lt__advise *) *padvise)->try_ext = 1; + return 0; +} + +int +lt_dladvise_resident (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + ((lt__advise *) *padvise)->is_resident = 1; + return 0; +} + +int +lt_dladvise_local (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + ((lt__advise *) *padvise)->is_symlocal = 1; + return 0; +} + +int +lt_dladvise_global (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + ((lt__advise *) *padvise)->is_symglobal = 1; + return 0; +} + +static lt__advise * +advise_dup (lt__advise *advise) +{ + lt__advise *dup = (lt__advise *) lt__zalloc (sizeof (lt__advise)); + return memcpy (dup, advise, sizeof (lt__advise)); +} + +/* Libtool-1.5.x interface for loading a new module named FILENAME. */ +lt_dlhandle +lt_dlopen (const char *filename) +{ + return lt_dlopenadvise (filename, NULL); +} + + +/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with MODULE_EXT appended + instead. */ +lt_dlhandle +lt_dlopenext (const char *filename) +{ + lt_dlhandle handle = 0; + lt_dladvise advise; + + if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise)) + handle = lt_dlopenadvise (filename, advise); + + lt_dladvise_destroy (&advise); + return handle; +} + + +lt_dlhandle +lt_dlopenadvise (const char *filename, lt_dladvise advise) +{ + lt_dlhandle handle = 0; + int errors = 0; - /* If we found FILENAME, stop searching -- whether we were able to - load the file as a module or not. If the file exists but loading - failed, it is better to return an error message here than to - report FILE_NOT_FOUND when the alternatives (foo.so etc) are not - in the module search path. */ - if (handle || ((errors > 0) && !file_not_found ())) + /* Can't have symbols hidden and visible at the same time! */ + if (advise + && ((lt__advise *) advise)->is_symlocal + && ((lt__advise *) advise)->is_symglobal) { - FREE (tmp); - return handle; + LT__SETERROR (CONFLICTING_FLAGS); + return 0; } -#if defined(LT_MODULE_EXT) - /* Try appending MODULE_EXT. */ - if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) + if (!filename + || !advise + || !((lt__advise *) advise)->try_ext + || has_library_ext (filename)) { - FREE (tmp); - tmp = MALLOC (char, len + LT_STRLEN (shlib_ext) + 1); - if (!tmp) - return 0; + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgot to reset handle... */ + if (try_dlopen (&handle, filename, NULL, advise) != 0) + return 0; - strcpy (tmp, filename); + return handle; } else { - tmp[len] = LT_EOS_CHAR; - } + assert (filename); - strcat(tmp, shlib_ext); - errors = try_dlopen (&handle, tmp); + /* First try appending ARCHIVE_EXT. */ + errors += try_dlopen (&handle, filename, archive_ext, advise); - /* As before, if the file was found but loading failed, return now - with the current error message. */ - if (handle || ((errors > 0) && !file_not_found ())) - { - FREE (tmp); - return handle; - } + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && !file_not_found ())) + return handle; + +#if defined(LT_MODULE_EXT) + /* Try appending SHLIB_EXT. */ + errors = try_dlopen (&handle, filename, shlib_ext, advise); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && !file_not_found ())) + return handle; #endif + } /* Still here? Then we really did fail to locate any of the file names we tried. */ LT__SETERROR (FILE_NOT_FOUND); - FREE (tmp); return 0; } @@ -2020,7 +2132,7 @@ lt_dlmakeresident (lt_dlhandle handle) } else { - LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + ((lt__handle *) handle)->info.is_resident = 1; } return errors; @@ -2040,7 +2152,6 @@ lt_dlisresident (lt_dlhandle handle) - /* --- MODULE INFORMATION --- */ typedef struct { diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index f25bbe00e..bd7666107 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -1,6 +1,7 @@ /* ltdl.h -- generic dlopen functions - Copyright (C) 1998-2000, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1998-2000, 2004, 2005, + 2007 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -42,7 +43,6 @@ LT_BEGIN_C_DECLS /* LT_STRLEN can be used safely on NULL pointers. */ #define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) - /* --- DYNAMIC MODULE LOADING API --- */ @@ -64,20 +64,25 @@ LT_SCOPE int lt_dlforeachfile ( int (*func) (const char *filename, void *data), void *data); +/* User module loading advisors. */ +LT_SCOPE int lt_dladvise_init (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_destroy (lt_dladvise *advise); +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); + /* Portable libltdl versions of the system dlopen() API. */ LT_SCOPE lt_dlhandle lt_dlopen (const char *filename); LT_SCOPE lt_dlhandle lt_dlopenext (const char *filename); +LT_SCOPE lt_dlhandle lt_dlopenadvise (const char *filename, + lt_dladvise advise); LT_SCOPE void * lt_dlsym (lt_dlhandle handle, const char *name); LT_SCOPE const char *lt_dlerror (void); LT_SCOPE int lt_dlclose (lt_dlhandle handle); -/* Module residency management. */ -LT_SCOPE int lt_dlmakeresident (lt_dlhandle handle); -LT_SCOPE int lt_dlisresident (lt_dlhandle handle); - - /* --- PRELOADED MODULE SUPPORT --- */ @@ -126,6 +131,11 @@ typedef struct { char * name; /* module name */ int ref_count; /* number of times lt_dlopened minus number of times lt_dlclosed. */ + unsigned int is_resident:1; /* module can't be unloaded. */ + unsigned int is_symglobal:1; /* module symbols can satisfy + subsequently loaded modules. */ + unsigned int is_symlocal:1; /* module symbols are only available + locally. */ } lt_dlinfo; LT_SCOPE const lt_dlinfo *lt_dlgetinfo (lt_dlhandle handle); @@ -138,6 +148,12 @@ LT_SCOPE int lt_dlhandle_map (lt_dlinterface_id iface, int (*func) (lt_dlhandle handle, void *data), void *data); + + +/* Deprecated module residency management API. */ +LT_SCOPE int lt_dlmakeresident (lt_dlhandle handle); +LT_SCOPE int lt_dlisresident (lt_dlhandle handle); + #define lt_ptr void * LT_END_C_DECLS