libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 329-gary-allow-RTLD_GLOBAL


From: Gary V. Vaughan
Subject: Re: 329-gary-allow-RTLD_GLOBAL
Date: Tue, 1 May 2007 15:33:37 +0100

Sorry for the delay.

In this version, I decided to go with the traditional _init and _destroy in the same scope after all, since we still need to provide lt_dladvise_destroy for the case where lt_dladvise_init works but an error between there and calling lt_dlopenadvise requires bailing out without trying to load the module.

I've added a test, which tries to be sympathetic to architectures that have no loaders that listen to advise, but will probably take a few iterations to shake out spurious failures on some hosts.

I've also added documentation.

Okay to commit?

  Index: ChangeLog
  from  Gary V. Vaughan  <address@hidden>

        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.
  Index: Makefile.am
  ===================================================================
  RCS file: /sources/libtool/libtool/Makefile.am,v
  retrieving revision 1.218
  diff -u -p -u -r1.218 Makefile.am
  --- Makefile.am 26 Apr 2007 22:34:05 -0000 1.218
  +++ Makefile.am 1 May 2007 14:03:54 -0000
  @@ -443,6 +443,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 \
  Index: NEWS
  ===================================================================
  RCS file: /sources/libtool/libtool/NEWS,v
  retrieving revision 1.203
  diff -u -p -u -r1.203 NEWS
  --- NEWS 23 Apr 2007 17:10:16 -0000 1.203
  +++ NEWS 1 May 2007 14:04:01 -0000
  @@ -8,10 +8,6 @@ New in 2.1a: 2007-??-??; CVS version 2.1
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.1
       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 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: doc/libtool.texi
  ===================================================================
  RCS file: /sources/libtool/libtool/doc/libtool.texi,v
  retrieving revision 1.226
  diff -u -p -u -r1.226 libtool.texi
  --- doc/libtool.texi 3 Apr 2007 19:09:39 -0000 1.226
  +++ doc/libtool.texi 1 May 2007 14:04:19 -0000
  @@ -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
   Every lt_dlopened module has a handle associated with it.
   @end deftp

  address@hidden {Type} lt_dladvise
  address@hidden is used to control optional module loading modes.
  +If it is not used, the default mode of the underlying system module
  +loader is used.
  address@hidden 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,91 @@ to be able to @code{dlopen} such librari
   transparently.
   @end deftypefun

  address@hidden int lt_dladvise_init (lt_dladvise address@hidden)
  +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} paramater needs to be initialised by this function
+before it can be used. Any memory used by @var{advise} is automatically
  +recycled when it is passed to @code{lt_dlopenadvise}.
  +
+On failure, @code{lt_dladvise_init} returns non-zero and sets an error
  +message that can be retrieved with @code{lt_dlerror}.
  address@hidden deftypefun
  +
  address@hidden int lt_dladvise_destroy (lt_dladvise address@hidden)
  +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}.
  address@hidden deftypefun
  +
  address@hidden int lt_dladvise_ext (lt_dladvise address@hidden)
  +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
  address@hidden (filename)}:
  +
  address@hidden
  +lt_dlhandle
  +my_dlopenext (const char *filename)
  address@hidden
  +  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;
  address@hidden
  address@hidden example
  +
+On failure, @code{lt_dladvise_ext} returns non-zero and sets an error
  +message that can be retrieved with @code{lt_dlerror}.
  address@hidden deftypefun
  +
  address@hidden int lt_dladvise_global (lt_dladvise address@hidden)
+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}.
  address@hidden deftypefun
  +
  address@hidden int lt_dladvise_local (lt_dladvise address@hidden)
+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.
  +
+On failure, @code{lt_dladvise_local} returns non-zero and sets an error
  +message that can be retrieved with @code{lt_dlerror}.
  address@hidden deftypefun
  +
  address@hidden int lt_dladvise_resident (lt_dladvise address@hidden)
+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}.
  address@hidden 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 +3944,16 @@ Some of the internal information about e
   maintained by libltdl is available to the user, in the form of this
   structure:

address@hidden {Type} {struct} lt_dlinfo @{ @w{char address@hidden;} @w{char address@hidden;} @w{int @var{ref_count};} @w{lt_module @var {module};address@hidden address@hidden {Type} {struct} lt_dlinfo @{ @w{char address@hidden;} @w{char address@hidden;} @w{int @var{ref_count};} @w{int @var {is_resident};} @w{int @var{is_symglobal};} @w{int @var{is_symlocal};address@hidden
   @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: libltdl/lt_dlloader.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/lt_dlloader.c,v
  retrieving revision 1.9
  diff -u -p -u -r1.9 lt_dlloader.c
  --- libltdl/lt_dlloader.c 25 Mar 2007 12:12:42 -0000 1.9
  +++ libltdl/lt_dlloader.c 1 May 2007 14:04:19 -0000
  @@ -1,6 +1,6 @@
   /* lt_dlloader.c -- 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
  Index: libltdl/ltdl.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/ltdl.c,v
  retrieving revision 1.248
  diff -u -p -u -r1.248 ltdl.c
  --- libltdl/ltdl.c 25 Mar 2007 12:12:42 -0000 1.248
  +++ libltdl/ltdl.c 1 May 2007 14:04:22 -0000
  @@ -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 Softw
   #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
   /* 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 ch
                                       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 dlhondle 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, con

       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, con

   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 *handl
        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 *handl

   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
         /* 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, cons
   }

   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, vo

     /* 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, vo
      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
         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

     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

     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
        {
          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
         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

    cleanup:
     FREE (dir);
  +  FREE (try);
     FREE (name);
     if (!canonical)            /* was MEMREASSIGNed */
       FREE (base_name);
  @@ -1355,18 +1399,6 @@ try_dlopen (lt_dlhandle *phandle, const
     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;
  +}
  +
  +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;
  +}

  -  strcpy (tmp, filename);
  -  strcat (tmp, archive_ext);
  -  errors = try_dlopen (&handle, tmp);
  -
  -  /* 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 ()))
  +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.5x 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;
  +
  +  /* 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))
  -    {
  -      FREE (tmp);
  -      tmp = MALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
  -      if (!tmp)
  -     return 0;
  +  if (!filename
  +      || !advise
  +      || !((lt__advise *) advise)->try_ext
  +      || has_library_ext (filename))
  +    {
+ /* 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 {
  Index: libltdl/ltdl.h
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/ltdl.h,v
  retrieving revision 1.84
  diff -u -p -u -r1.84 ltdl.h
  --- libltdl/ltdl.h 25 Mar 2007 12:12:42 -0000 1.84
  +++ libltdl/ltdl.h 1 May 2007 14:04:22 -0000
  @@ -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. */
  +  int                is_resident:1;  /* module can't be unloaded. */
  +  int                is_symglobal:1; /* module symbols can satisfy
  +                                subsequently loaded modules.  */
  +  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_dl
                                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
  Index: libltdl/libltdl/lt__private.h
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/libltdl/lt__private.h,v
  retrieving revision 1.13
  diff -u -p -u -r1.13 lt__private.h
  --- libltdl/libltdl/lt__private.h 25 Mar 2007 12:12:43 -0000 1.13
  +++ libltdl/libltdl/lt__private.h 1 May 2007 14:04:41 -0000
  @@ -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: libltdl/libltdl/lt_dlloader.h
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/libltdl/lt_dlloader.h,v
  retrieving revision 1.3
  diff -u -p -u -r1.3 lt_dlloader.h
  --- libltdl/libltdl/lt_dlloader.h 25 Mar 2007 12:12:43 -0000 1.3
  +++ libltdl/libltdl/lt_dlloader.h 1 May 2007 14:04:41 -0000
  @@ -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: libltdl/libltdl/lt_error.h
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/libltdl/lt_error.h,v
  retrieving revision 1.5
  diff -u -p -u -r1.5 lt_error.h
  --- libltdl/libltdl/lt_error.h 25 Mar 2007 12:12:43 -0000 1.5
  +++ libltdl/libltdl/lt_error.h 1 May 2007 14:04:41 -0000
  @@ -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: libltdl/loaders/dld_link.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/loaders/dld_link.c,v
  retrieving revision 1.8
  diff -u -p -u -r1.8 dld_link.c
  --- libltdl/loaders/dld_link.c 25 Mar 2007 12:12:43 -0000 1.8
  +++ libltdl/loaders/dld_link.c 1 May 2007 14:04:41 -0000
  @@ -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: libltdl/loaders/dlopen.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/loaders/dlopen.c,v
  retrieving revision 1.9
  diff -u -p -u -r1.9 dlopen.c
  --- libltdl/loaders/dlopen.c 25 Mar 2007 12:12:43 -0000 1.9
  +++ libltdl/loaders/dlopen.c 1 May 2007 14:04:41 -0000
  @@ -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: libltdl/loaders/dyld.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/loaders/dyld.c,v
  retrieving revision 1.7
  diff -u -p -u -r1.7 dyld.c
  --- libltdl/loaders/dyld.c 25 Mar 2007 12:12:43 -0000 1.7
  +++ libltdl/loaders/dyld.c 1 May 2007 14:04:42 -0000
  @@ -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: libltdl/loaders/load_add_on.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/loaders/load_add_on.c,v
  retrieving revision 1.8
  diff -u -p -u -r1.8 load_add_on.c
  --- libltdl/loaders/load_add_on.c 25 Mar 2007 12:12:43 -0000 1.8
  +++ libltdl/loaders/load_add_on.c 1 May 2007 14:04:42 -0000
  @@ -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: libltdl/loaders/loadlibrary.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/loaders/loadlibrary.c,v
  retrieving revision 1.14
  diff -u -p -u -r1.14 loadlibrary.c
  --- libltdl/loaders/loadlibrary.c 25 Mar 2007 12:12:43 -0000 1.14
  +++ libltdl/loaders/loadlibrary.c 1 May 2007 14:04:43 -0000
  @@ -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: libltdl/loaders/preopen.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/loaders/preopen.c,v
  retrieving revision 1.12
  diff -u -p -u -r1.12 preopen.c
  --- libltdl/loaders/preopen.c 25 Mar 2007 12:12:43 -0000 1.12
  +++ libltdl/loaders/preopen.c 1 May 2007 14:04:44 -0000
  @@ -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_
      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: libltdl/loaders/shl_load.c
  ===================================================================
  RCS file: /sources/libtool/libtool/libltdl/loaders/shl_load.c,v
  retrieving revision 1.9
  diff -u -p -u -r1.9 shl_load.c
  --- libltdl/loaders/shl_load.c 25 Mar 2007 12:12:43 -0000 1.9
  +++ libltdl/loaders/shl_load.c 1 May 2007 14:04:44 -0000
  @@ -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: tests/lt_dladvise.at
  ===================================================================
  RCS file: tests/lt_dladvise.at
  diff -N tests/lt_dladvise.at
  --- /dev/null 1 Jan 1970 00:00:00 -0000
  +++ tests/lt_dladvise.at 1 May 2007 14:04:45 -0000
  @@ -0,0 +1,292 @@
+# lt_dlexit.at -- test libltdl functionality -*- Autotest -*-
  +#
  +#   Copyright (C) 2007 Free Software Foundation, Inc.
  +#   Written by Gary V. Vaughan, 2007
  +#
  +#   This file is part of GNU Libtool.
  +#
  +# GNU Libtool is free software; you can redistribute it and/or
  +# modify it under the terms of the GNU General Public License as
  +# published by the Free Software Foundation; either version 2 of
  +# the License, or (at your option) any later version.
  +#
  +# GNU Libtool is distributed in the hope that it will be useful,
  +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  +# GNU General Public License for more details.
  +#
  +# You should have received a copy of the GNU General Public License
  +# along with GNU Libtool; see the file COPYING.  If not, a copy
  +# can be downloaded from  http://www.gnu.org/licenses/gpl.html,
  +# or obtained by writing to the Free Software Foundation, Inc.,
  +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  +####
  +
  +# Try to keep the new interfaces of HEAD separate from those of
  +# branch-1-5 to facilitate testing of older releases.
  +
  +AT_SETUP([lt_dlopenadvise library loading])
  +AT_KEYWORDS([libltdl])
  +
  +AT_DATA([main.c],
  +[[#include <ltdl.h>
  +#include <stdio.h>
  +
  +typedef int funcp (int);
  +
  +static int errors = 0;
  +
  +static void
  +complain (const char *msg)
  +{
  +  const char *errmsg = lt_dlerror ();
  +  fprintf (stderr, "%s", msg);
  +  if (errmsg)
  +    fprintf (stderr, ": %s\n", errmsg);
  +  else
  +    fprintf (stderr, ".\n");
  +  ++errors;
  +}
  +
  +static lt_dlhandle
  +moduleopen (const char *filename, lt_dladvise advise)
  +{
  +  lt_dlhandle handle;
  +
  +  handle = lt_dlopenadvise (filename, advise);
  +  if (!handle)
  +    {
  +      fprintf (stderr, "can't open the module %s!\n", filename);
  +      complain ("error was");
  +    }
  +
  +  return handle;
  +}
  +
  +static int
+moduletest (lt_dlhandle handle, const char *fname, const char *vname)
  +{
  +  funcp *f = (funcp *) lt_dlsym (handle, fname);
  +  int   *v = (int *)   lt_dlsym (handle, vname);
  +
  +  if (!f)
  +    {
  +      fprintf (stderr, "function `%s' not found\n", fname);
  +      ++errors;
  +      return -1;
  +    }
  +  if (!v)
  +    {
  +      fprintf (stderr, "variable `%s' not found\n", vname);
  +      ++errors;
  +      return -1;
  +    }
  +  return f (*v);
  +}
  +
  +void
  +hint_ext (void)
  +{
  +  lt_dlhandle handle;
  +  lt_dladvise advise;
  +
  +  if (lt_dladvise_init (&advise) || lt_dladvise_ext (&advise))
  +    complain ("error setting advise ext");
  +
  +  handle = moduleopen ("moddepend", advise);
  +
  +  if (handle)
  +    printf ("depend: %d\n", moduletest (handle, "g", "j"));
  +
  +  lt_dladvise_destroy (&advise);
  +}
  +
  +void
  +hint_resident (void)
  +{
  +  const lt_dlinfo *info;
  +  lt_dlhandle handle;
  +  lt_dladvise advise;
  +
  +  if (lt_dladvise_init (&advise) || lt_dladvise_resident (&advise))
  +    complain ("error setting advise resident");
  +
  +  handle = moduleopen ("modresident.la", advise);
  +
  +  if (handle)
  +    {
  +      info = lt_dlgetinfo (handle);
  +      if (!info->is_resident)
  +     complain ("error taking advise resident");
  +
  +      /* cannot close resident modules */
  +      if (lt_dlclose (handle) == 0)
  +     complain ("successfully unloaded resident module");
  +
+ printf ("resident: %d\n", moduletest (handle, "func", "numb"));
  +    }
  +
  +  lt_dladvise_destroy (&advise);
  +}
  +
  +void
  +hint_local (void)
  +{
  +  const lt_dlinfo *info;
  +  lt_dlhandle handle;
  +  lt_dladvise advise;
  +
  +  if (lt_dladvise_init (&advise) || lt_dladvise_local (&advise))
  +    complain ("error setting advise local");
  +
  +  handle = moduleopen ("modlocal.la", advise);
  +
  +  if (handle)
  +    {
  +      info = lt_dlgetinfo (handle);
  +      printf ("local: %d\n", moduletest (handle, "f", "i"));
  +
  +      /* If the symlocal hint was taken, don't unload this module
+ and test that our local symbolnames won't clash with modglobal. */
  +      if (!info->is_symlocal && lt_dlclose (handle))
  +     complain ("error unloading modlocal");
  +    }
  +
  +  lt_dladvise_destroy (&advise);
  +}
  +
  +void
  +hint_global (void)
  +{
  +  const lt_dlinfo *info;
  +  lt_dlhandle handle;
  +  lt_dladvise advise;
  +
  +  if (lt_dladvise_init (&advise) || lt_dladvise_global (&advise))
  +    complain ("error setting advise global");
  +
  +  handle = moduleopen ("modglobal.la", advise);
  +
  +  if (handle)
  +    {
  +      info = lt_dlgetinfo (handle);
  +      printf ("global: %d\n", moduletest (handle, "f", "i"));
  +
+ /* Don't attempt to load moddepend unless modglobal was successfully
  +         loaded and the symglobal hint was taken.  */
  +      if (info && info->is_symglobal)
  +        {
  +          hint_ext ();
  +        }
  +      else
  +        {
+ /* Fake the output so the test won't fail when using a dlloader
  +             unable to take symglobal hints.  */
  +          printf ("depend: 5\n");
  +        }
  +    }
  +
  +  lt_dladvise_destroy (&advise);
  +}
  +
  +int
  +main (int argc, char **argv)
  +{
  +
  +  LTDL_SET_PRELOADED_SYMBOLS();
  +
  +  if (lt_dlinit() != 0)
  +    {
+ fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
  +      return 1;
  +    }
  +
  +  hint_resident ();
  +  hint_local ();
  +  hint_global ();
  +
  +  if (lt_dlexit () != 0)
  +    complain ("error during exit");
  +
  +  return (errors != 0);
  +}
  +]])
  +
  +AT_DATA([modresident.c],
  +[[#ifdef __cplusplus
  +extern "C" {
  +#endif
  +int func (int x) { return x / 3; }
  +int numb = 7;
  +#ifdef __cplusplus
  +}
  +#endif
  +]])
  +
  +AT_DATA([modlocal.c],
  +[[#ifdef __cplusplus
  +extern "C" {
  +#endif
  +int f (int x) { return (x * x) / 10; }
  +int i = 6;
  +#ifdef __cplusplus
  +}
  +#endif
  +]])
  +
  +AT_DATA([modglobal.c],
  +[[#ifdef __cplusplus
  +extern "C" {
  +#endif
  +int f (int x) { return x - 1; }
  +int i = 5;
  +#ifdef __cplusplus
  +}
  +#endif
  +]])
  +
  +AT_DATA([moddepend.c],
  +[[#ifdef __cplusplus
  +extern "C" {
  +#endif
  +extern int f (int), i;
  +int g (int x) { return f (i) + x - 3; }
  +int j = 4;
  +#ifdef __cplusplus
  +}
  +#endif
  +]])
  +
  +AT_DATA([expout],
  +[[resident: 2
  +local: 3
  +global: 4
  +depend: 5
  +]])
  +
  +: ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
  +: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
  +
  +CPPFLAGS="$CPPFLAGS $LTDLINCL"
  +LDFLAGS="$LDFLAGS"
  +
  +$CC $CPPFLAGS $CFLAGS -c main.c
  +for file in modresident modlocal modglobal moddepend; do
  +  $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c $file.c
+ AT_CHECK([$LIBTOOL --mode=link $CC -module $CFLAGS $LDFLAGS -o $file.la \ + $file.lo -rpath /foo -avoid-version], [], [ignore], [ignore])
  +done
  +
  +# TODO: test -dlpreopen
  +for dlopen in -dlopen; do
+ AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main main.$OBJEXT \ + $dlopen modresident.la $dlopen modlocal.la $dlopen modglobal.la \
  +           $dlopen moddepend.la $LIBLTDL],
  +           [], [ignore], [ignore])
  +  LT_AT_NOINST_EXEC_CHECK([./main],
+ [$dlopen modresident.la $dlopen modlocal.la $dlopen modglobal.la \
  +            $dlopen moddepend.la],
  +        [], [expout], [])
  +done
  +
  +AT_CLEANUP

Cheers,
        Gary
--
  ())_.              Email me: address@hidden
  ( '/           Read my blog: http://blog.azazil.net
  / )=         ...and my book: http://sources.redhat.com/autobook
`(_~)_ Join my AGLOCO Network: http://www.agloco.com/r/BBBS7912




Attachment: PGP.sig
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]