]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
Without this patch, lt_dlopen always opens modules with symbol
authorGary V. Vaughan <gary@gnu.org>
Tue, 8 May 2007 14:38:50 +0000 (14:38 +0000)
committerGary V. Vaughan <gary@gnu.org>
Tue, 8 May 2007 14:38:50 +0000 (14:38 +0000)
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.

16 files changed:
ChangeLog
Makefile.am
NEWS
doc/libtool.texi
libltdl/libltdl/lt__private.h
libltdl/libltdl/lt_dlloader.h
libltdl/libltdl/lt_error.h
libltdl/loaders/dld_link.c
libltdl/loaders/dlopen.c
libltdl/loaders/dyld.c
libltdl/loaders/load_add_on.c
libltdl/loaders/loadlibrary.c
libltdl/loaders/preopen.c
libltdl/loaders/shl_load.c
libltdl/ltdl.c
libltdl/ltdl.h

index ab7cac970f0d468401b3e3b464baa428077eb41a..0ebab8069eb3e8199bdba331036221147fecb552 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2007-05-08  Gary V. Vaughan  <gary@gnu.org>
+
+       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  <Ralf.Wildenhues@gmx.de>
 
        * libltdl/config/ltmain.m4sh (func_mode_link): When adding
index bf61fab673da7226794bb59e49704b6033712ef9..3d086eed51bf16e46b10f2583378055e3b26c53c 100644 (file)
@@ -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 6c0d5d591b1c417d658d7f0a23e25f2daa3b5945..8792f6360774931227b220f1b9b7139d87155577 100644 (file)
--- 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.
index 8772093085c80982a0341ed6b954f60c5a3e4954..8b6d3e906bab97af3c3f15976c7a3a855934e243 100644 (file)
@@ -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
index 5c21b15ae85efaf92d91f0971176dd1f79174a59..c258df8e124b27b16fe1396cc76c925b3dcd17ef 100644 (file)
@@ -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 --- */
 
index 3cff1b68d8b147091113a1b4ed06886d6e08b71b..46c8b4db3a7b048918a3ecc353af8ab2ca9300cc 100644 (file)
@@ -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,
index 68b94f5b79f4910645ae5f9bc0467888ea411ffd..dbb462dbf41909ff26043df2dad9f6eee11ee0cf 100644 (file)
@@ -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 {
index e4370abcd1b344dd9ae73711953bf8eb331dd6ef..189ee3b09f63c0408bd04aacb6d9407b95a80418 100644 (file)
@@ -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);
 
index c3711af963e35732a5603643ae97980a07cbe186..5313bc795d666c94f227ccc44f4cec1591178fd8 100644 (file)
@@ -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)
     {
index 6b9fc87222921d4814aede5c1596a82ceb92c73d..216b4260262d4c0d9829a50c4f500ba511b77ae4 100644 (file)
@@ -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;
index 9b2f3afdda51a961349bf72016d5c67b9fa89e27..f79604ff27056b190746a4ebef474d0bffde6fd3 100644 (file)
@@ -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;
 
index 4d77ec17089effb8a16dcb0ec1bdea69eb56d415..71f90c718824d29267f49bd1dab58fa0d3bd7438 100644 (file)
@@ -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;
index 4497d68138103010d55c18b330b6a3b8b9ed5573..82066fec6bc0fe9e11ad6c5a12bead60c6a4d8db 100644 (file)
@@ -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;
index 2d8844ee8366022e3b1ac81f14577e0d3094e9a7..15f00bdfff26a759dfef09944c49137286100e39 100644 (file)
@@ -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);
index 7aced2bb916cf4d4e26d56c7f4b4987db55eaa3d..79769cc3b0dfa7e2202421e58b93e5839d9c8a3c 100644 (file)
@@ -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)
 
 
 
-\f
 /* --- MODULE INFORMATION --- */
 
 typedef struct {
index f25bbe00ede5c2c48f47894be3f0a0c4d22998ae..bd7666107472d4b21257e192b9c32770bc0ff3eb 100644 (file)
@@ -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)
 
-
 \f
 /* --- 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);
-
 
 
-\f
 /* --- 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