]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
Add a test to simulate a failure visible on systems which
authorGary V. Vaughan <gary@gnu.org>
Sun, 24 Jun 2007 20:46:47 +0000 (20:46 +0000)
committerGary V. Vaughan <gary@gnu.org>
Sun, 24 Jun 2007 20:46:47 +0000 (20:46 +0000)
need a library prefix like 'lib', such as BeOS.  Fix a number
of bugs exposed by this test in order for it to pass.
Currently the prefix is hardcoded as 'lib', as I am not aware
of systems that require a different prefix:

* libltdl/loaders/preopen.c (lt_dlpreload_open):  Move error
condition out of test loop to be sure that each originator is
tried, instead of erroring out if the first doesn't match.
Support passing NULL as the originator to load all preloaded
modules originating in the program itself.
* libltdl/lt_dlloader.c (lt_dlloader_dump): New debug function.
* libltdl/libltdl/lt_dlloader.h (lt_dlloader_dump): Declare it
when LT_DEBUG_LOADERS is defined at compile time.
* libltdl/ltdl.c (lt_dlinit): Dump loader list after successful
initialisation.
(tryall_dlopen): Add a new VTABLE parameter to force use of a
specific loader in preference to trying every loader in turn.
Adjust all callers.
(try_dlopen): Always see whether a module was preloaded for
module names with no directory component before searching the
filesystem for a match.
* libltdl/m4/libtool.m4 (_LT_CMD_GLOBAL_SYMBOLS): Declare
a new global_symbol_to_c_name_address_lib_prefix variable.
(global_symbol_to_c_name_address_lib_prefix): The sed
expressions to use when a lib prefix is enforced need to be
slightly different to work with preloaded modules.
* libltdl/config/ltmain.m4sh (func_generate_dlsyms): In order
to name preloaded symbols correctly for the lookup algorithm
to work when the loaded module file must be prefixed with lib.
Use global_symbol_to_c_name_address_lib_prefix when
need_lib_prefix is other than no.
* tests/need_lib_prefix.at: New test to check for breakage on
hosts where need_lib_prefix is unknown.
* Makefile.am (TESTSUITE_AT): Add new test.
* tests/TODO: Note missing tests that would have caught some
of the latent bugs fixed by this patch.
* HACKING: Document libltdl keyword.
* NEWS: Updated.

12 files changed:
ChangeLog
HACKING
Makefile.am
NEWS
libltdl/config/ltmain.m4sh
libltdl/libltdl/lt_dlloader.h
libltdl/loaders/preopen.c
libltdl/lt_dlloader.c
libltdl/ltdl.c
libltdl/m4/libtool.m4
tests/TODO [new file with mode: 0644]
tests/need_lib_prefix.at [new file with mode: 0644]

index 2708323d3484bb20abe0d34ed9d9ca4980488898..e997386136052201a3bdbc8fa61436243d3a4248 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2007-06-24  Gary V. Vaughan  <gary@gnu.org>
+
+       Add a test to simulate a failure visible on systems which
+       need a library prefix like 'lib', such as BeOS.  Fix a number
+       of bugs exposed by this test in order for it to pass.
+       Currently the prefix is hardcoded as 'lib', as I am not aware
+       of systems that require a different prefix:
+
+       * libltdl/loaders/preopen.c (lt_dlpreload_open):  Move error
+       condition out of test loop to be sure that each originator is
+       tried, instead of erroring out if the first doesn't match.
+       Support passing NULL as the originator to load all preloaded
+       modules originating in the program itself.
+       * libltdl/lt_dlloader.c (lt_dlloader_dump): New debug function.
+       * libltdl/libltdl/lt_dlloader.h (lt_dlloader_dump): Declare it
+       when LT_DEBUG_LOADERS is defined at compile time.
+       * libltdl/ltdl.c (lt_dlinit): Dump loader list after successful
+       initialisation.
+       (tryall_dlopen): Add a new VTABLE parameter to force use of a
+       specific loader in preference to trying every loader in turn.
+       Adjust all callers.
+       (try_dlopen): Always see whether a module was preloaded for
+       module names with no directory component before searching the
+       filesystem for a match.
+       * libltdl/m4/libtool.m4 (_LT_CMD_GLOBAL_SYMBOLS): Declare
+       a new global_symbol_to_c_name_address_lib_prefix variable.
+       (global_symbol_to_c_name_address_lib_prefix): The sed
+       expressions to use when a lib prefix is enforced need to be
+       slightly different to work with preloaded modules.
+       * libltdl/config/ltmain.m4sh (func_generate_dlsyms): In order
+       to name preloaded symbols correctly for the lookup algorithm
+       to work when the loaded module file must be prefixed with lib.
+       Use global_symbol_to_c_name_address_lib_prefix when
+       need_lib_prefix is other than no.
+       * tests/need_lib_prefix.at: New test to check for breakage on
+       hosts where need_lib_prefix is unknown.
+       * Makefile.am (TESTSUITE_AT): Add new test.
+       * tests/TODO: Note missing tests that would have caught some
+       of the latent bugs fixed by this patch.
+       * HACKING: Document libltdl keyword.
+       * NEWS: Updated.
+
 2007-06-24  Gary V. Vaughan  <gary@gnu.org>
 
        Reenable compilation of libltdl with C++:
diff --git a/HACKING b/HACKING
index d57d94085da671cdb50203034fb82c65a20f8f8c..02bdef0d6d648578a7d65ba1373aa34f5df89ec7 100644 (file)
--- a/HACKING
+++ b/HACKING
@@ -51,6 +51,10 @@ and is not part of a release distribution.
 3. Test Suite
 =============
 
+* When writing tests, make sure the link invocation (first argument to
+  AT_CHECK) is on a single line so that 'testsuite -x' displays the
+  whole thing.
+
 * Use
     make check TESTSUITEFLAGS=-V
     make check-local
@@ -60,6 +64,7 @@ and is not part of a release distribution.
 * The new Autotest testsuite uses keywords to denote test features:
     autoconf           needs Autoconf
     automake           needs Automake
+    libltdl            exercises the `libltdl' library
     libtool            exercises the `libtool' script
     libtoolize         exercises the `libtoolize' script
     recursive          runs the suite recursively, with a modified
index 90286b5500bc68fba5e4f74a794eb6caad6510f2..c503374438e93b0a513aca667421c89444c90d0a 100644 (file)
@@ -447,6 +447,7 @@ TESTSUITE_AT        = tests/testsuite.at \
                  tests/am-subdir.at \
                  tests/lt_dlexit.at \
                  tests/lt_dladvise.at \
+                 tests/need_lib_prefix.at \
                  tests/standalone.at \
                  tests/subproject.at \
                  tests/nonrecursive.at \
diff --git a/NEWS b/NEWS
index 8792f6360774931227b220f1b9b7139d87155577..909100cc2b923bc7a37c6d80a77a6906d58dc90e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,12 +2,6 @@ NEWS - list of user-visible changes between releases of GNU Libtool
 
 New in 2.1a: 2007-??-??; CVS version 2.1a, Libtool team:
 
-* Regressions over 1.5.x that may be fixed later:
-
-  - On systems which need a library prefix like `lib', such as BeOS,
-    libltdl currently does not build.  The new structure of libltdl with
-    preopened modules exposes some long-lived bugs here.
-
 * Important incompatible changes and obsoleted features:
 
   - Removed deprecated APIs from libltdl: lt_dlcaller_register,
index 3030b98274b645945ee7e5ab5118e4716c940180..3903e21c7110e0ff1fc730dad867474e8f47c862 100644 (file)
@@ -1020,8 +1020,14 @@ lt_${my_prefix}_LTX_preloaded_symbols[] =
 {\
   { \"$my_originator\", (void *) 0 },"
 
-         eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
-
+         case $need_lib_prefix in
+         no)
+           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+           ;;
+         *)
+           eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+           ;;
+         esac
          $ECHO >> "$output_objdir/$my_dlsyms" "\
   {0, (void *) 0}
 };
index 46c8b4db3a7b048918a3ecc353af8ab2ca9300cc..9512b3538672752d1c59160b78307ae31943d57d 100644 (file)
@@ -81,6 +81,10 @@ LT_SCOPE const lt_dlvtable *lt_dlloader_get  (lt_dlloader loader);
 /* Type of a function to get a loader's vtable:  */
 typedef  const lt_dlvtable *lt_get_vtable      (lt_user_data data);
 
+#ifdef LT_DEBUG_LOADERS
+LT_SCOPE void          lt_dlloader_dump        (void);
+#endif
+
 LT_END_C_DECLS
 
 #endif /*!defined(LT_DLLOADER_H)*/
index 82066fec6bc0fe9e11ad6c5a12bead60c6a4d8db..664140be4e3010a1ddca8c8c1d2401db8163c8be 100644 (file)
@@ -322,7 +322,8 @@ lt_dlpreload (const lt_dlsymlist *preloaded)
 
 
 /* Open all the preloaded modules from the named originator, executing
-   a callback for each one.  */
+   a callback for each one.  If ORIGINATOR is NULL, then call FUNC for
+   each preloaded module from the program itself.  */
 int
 lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
 {
@@ -334,7 +335,8 @@ lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
   for (list = preloaded_symlists; list; list = list->next)
     {
       /* ...that was preloaded by the requesting ORIGINATOR... */
-      if (streq (list->symlist->name, originator))
+      if ((originator && streq (list->symlist->name, originator))
+          || (!originator && streq (list->symlist->name, "@PROGRAM@")))
        {
          const lt_dlsymlist *symbol;
          unsigned int idx = 0;
@@ -360,12 +362,12 @@ lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
                }
            }
        }
+    }
 
-      if (!found)
-       {
-         LT__SETERROR(CANNOT_OPEN);
-         ++errors;
-       }
+  if (!found)
+    {
+      LT__SETERROR(CANNOT_OPEN);
+      ++errors;
     }
 
   return errors;
index 438e92da0aad80aed28b3a586bc4f19897c99259..851bf413a27ebd38e8b0fcff32116d25b4473cb7 100644 (file)
@@ -97,6 +97,33 @@ lt_dlloader_add (const lt_dlvtable *vtable)
   return RETURN_SUCCESS;
 }
 
+#ifdef LT_DEBUG_LOADERS
+static void *
+loader_dump_callback (SList *item, void *userdata)
+{
+  const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata;
+  fprintf (stderr, ", %s", (vtable && vtable->name) ? vtable->name : "(null)");
+  return 0;
+}
+
+void
+lt_dlloader_dump (void)
+{
+  fprintf (stderr, "loaders: ");
+  if (!loaders)
+    {
+      fprintf (stderr, "(empty)");
+    }
+  else
+    {
+      const lt_dlvtable *head = (const lt_dlvtable *) loaders->userdata;
+      fprintf (stderr, "%s", (head && head->name) ? head->name : "(null)");
+      if (slist_tail (loaders))
+       slist_foreach (slist_tail (loaders), loader_dump_callback, NULL);
+    }
+  fprintf (stderr, "\n");
+}
+#endif
 
 /* An iterator for the global loader list: if LOADER is NULL, then
    return the first element, otherwise the following element.  */
index a8860aa8c7699d72e7d2bf6cc2dd4aeceb08c321..1f132ca8c852870180726a70a0c40eabf9732368 100644 (file)
@@ -1,7 +1,7 @@
 /* ltdl.c -- system independent dlopen wrapper
 
    Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
-                 2007 Free Software Foundation, Inc.
+                2007 Free Software Foundation, Inc.
    Written by Thomas Tanner, 1998
 
    NOTE: The canonical source of this file is maintained with the
@@ -120,7 +120,8 @@ static      int     try_dlopen            (lt_dlhandle *handle,
                                       lt_dladvise advise);
 static int     tryall_dlopen         (lt_dlhandle *handle,
                                       const char *filename,
-                                      lt_dladvise advise);
+                                      lt_dladvise advise,
+                                      const lt_dlvtable *vtable);
 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,
@@ -239,6 +240,10 @@ lt_dlinit (void)
 #endif /* HAVE_LIBDLLOADER */
     }
 
+#ifdef LT_DEBUG_LOADERS
+  lt_dlloader_dump();
+#endif
+
   return errors;
 }
 
@@ -332,17 +337,23 @@ lt_dlexit (void)
 }
 
 
-/* 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.  */
+/* Try VTABLE or, if VTABLE is NULL, all available loaders 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,
-              lt_dladvise advise)
+              lt_dladvise advise, const lt_dlvtable *vtable)
 {
   lt__handle * handle          = (lt__handle *) handles;
   const char * saved_error     = 0;
   int          errors          = 0;
 
+#ifdef LT_DEBUG_LOADERS
+  fprintf (stderr, "tryall_dlopen (%s, %s)\n",
+          filename ? filename : "(null)",
+          vtable ? vtable->name : "(ALL)");
+#endif
+
   LT__GETERROR (saved_error);
 
   /* check whether the module was already opened */
@@ -391,42 +402,60 @@ tryall_dlopen (lt_dlhandle *phandle, const char *filename,
     }
 
   {
-    const lt_dlvtable *vtable = 0;
-    lt_dlloader *loader = 0;
+    lt_dlloader loader = lt_dlloader_next (0);
+    const lt_dlvtable *loader_vtable;
 
-    while ((loader = (lt_dlloader *) lt_dlloader_next (loader)))
+    do
       {
        lt__advise *advise_taken = 0;
 
        if (advise)
          advise_taken = advise_dup ((lt__advise *) advise);
 
-       vtable = lt_dlloader_get (loader);
-       handle->module = (*vtable->module_open) (vtable->dlloader_data,
-                                                filename, advise_taken);
+       if (vtable)
+         loader_vtable = vtable;
+       else
+         loader_vtable = lt_dlloader_get (loader);
+
+#ifdef LT_DEBUG_LOADERS
+       fprintf (stderr, "Calling %s->module_open (%s)\n",
+                (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
+                filename ? filename : "(null)");
+#endif
+       handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
+                                                       filename, advise_taken);
+#ifdef LT_DEBUG_LOADERS
+       fprintf (stderr, "  Result: %s\n",
+                handle->module ? "Success" : "Failed");
+#endif
 
        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;
+               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);
       }
+    while (!vtable && (loader = lt_dlloader_next (loader)));
 
-    if (!loader)
+    /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
+       given but we exhausted all loaders without opening the module, bail
+       out!  */
+    if ((vtable && !handle->module)
+       || (!vtable && !loader))
       {
        FREE (handle->info.filename);
        ++errors;
        goto done;
       }
 
-    handle->vtable = vtable;
+    handle->vtable = loader_vtable;
   }
 
   LT__SETERRORSTR (saved_error);
@@ -474,9 +503,9 @@ tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
   if (prefix)
     {
       error += tryall_dlopen_module (handle, (const char *) 0,
-                                     prefix, filename, advise);
+                                    prefix, filename, advise);
     }
-  else if (tryall_dlopen (handle, filename, advise) != 0)
+  else if (tryall_dlopen (handle, filename, advise, 0) != 0)
     {
       ++error;
     }
@@ -493,7 +522,7 @@ find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
   /* 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, advise) == 0)
+  if (old_name && tryall_dlopen (handle, old_name, advise, 0) == 0)
     {
       return 0;
     }
@@ -513,14 +542,14 @@ find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
       if (!installed)
        {
          if (tryall_dlopen_module (handle, dir, objdir,
-                                   dlname, advise) == 0)
+                                   dlname, advise) == 0)
            return 0;
        }
 
       /* maybe it was moved to another directory */
       {
          if (dir && (tryall_dlopen_module (handle, (const char *) 0,
-                                           dir, dlname, advise) == 0))
+                                           dir, dlname, advise) == 0))
            return 0;
       }
     }
@@ -737,7 +766,7 @@ find_handle_callback (char *filename, void *data, void *data2)
 
   /* Try to dlopen the file, but do not continue searching in any
      case.  */
-  if (tryall_dlopen (handle, filename, advise) != 0)
+  if (tryall_dlopen (handle, filename, advise, 0) != 0)
     *handle = 0;
 
   return 1;
@@ -1093,7 +1122,7 @@ cleanup:
 /* Try to open FILENAME as a module. */
 static int
 try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
-            lt_dladvise advise)
+           lt_dladvise advise)
 {
   const char * saved_error     = 0;
   char *       canonical       = 0;
@@ -1107,6 +1136,12 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
   assert (phandle);
   assert (*phandle == 0);
 
+#ifdef LT_DEBUG_LOADERS
+  fprintf (stderr, "try_dlopen (%s, %s)\n",
+          filename ? filename : "(null)",
+          ext ? ext : "(null)");
+#endif
+
   LT__GETERROR (saved_error);
 
   /* dlopen self? */
@@ -1121,7 +1156,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
       /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
       ((lt__handle *) newhandle)->info.is_resident = 1;
 
-      if (tryall_dlopen (&newhandle, 0, advise) != 0)
+      if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
        {
          FREE (*phandle);
          return 1;
@@ -1210,6 +1245,35 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
     name[ext - base_name] = LT_EOS_CHAR;
   }
 
+  /* Before trawling through the filesystem in search of a module,
+     check whether we are opening a preloaded module.  */
+  if (!dir)
+    {
+      const lt_dlvtable *vtable        = lt_dlloader_find ("lt_preopen");
+
+      if (vtable)
+       {
+         *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
+
+         if (*phandle == NULL)
+           {
+             ++errors;
+             goto cleanup;
+           }
+         newhandle = *phandle;
+
+         if (tryall_dlopen (&newhandle, filename, advise, vtable) == 0)
+           {
+             goto register_handle;
+           }
+
+         /* If we're still here, there was no matching preloaded module,
+            so put things back as we found them, and continue searching.  */
+         FREE (*phandle);
+         newhandle = NULL;
+       }
+    }
+
   /* Check whether we are opening a libtool module (.la extension).  */
   if (ext && streq (ext, archive_ext))
     {
@@ -1225,16 +1289,14 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
         of libtool */
       int      installed = 1;
 
-
       /* Now try to open the .la file.  If there is no directory name
-         component, try to find it 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.  */
+        component, try to find it 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)
        {
-         const char *search_path;
+         const char *search_path = user_search_path;
 
-         search_path = user_search_path;
          if (search_path)
            file = find_file (user_search_path, base_name, &dir);
 
@@ -1277,7 +1339,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
       /* read the .la file */
       if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
            &old_name, &installed) != 0)
-       errors++;
+       ++errors;
 
       fclose (file);
 
@@ -1303,7 +1365,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
          newhandle = *phandle;
          /* find_module may replace newhandle */
          if (find_module (&newhandle, dir, libdir, dlname, old_name,
-                          installed, advise))
+                          installed, advise))
            {
              unload_deplibs (*phandle);
              ++errors;
@@ -1347,7 +1409,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
         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, advise)
+                                &newhandle, advise)
                   && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
                                    &newhandle, advise)
 #if defined(LT_MODULE_PATH_VAR)
@@ -1356,14 +1418,14 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
 #endif
 #if defined(LT_DLSEARCH_PATH)
                   && !find_handle (sys_dlsearch_path, base_name,
-                                   &newhandle, advise)
+                                   &newhandle, advise)
 #endif
                   )))
        {
-          if (tryall_dlopen (&newhandle, filename, advise) != 0)
-            {
-              newhandle = NULL;
-            }
+         if (tryall_dlopen (&newhandle, filename, advise, 0) != 0)
+           {
+             newhandle = NULL;
+           }
        }
 
       if (!newhandle)
@@ -1420,8 +1482,8 @@ file_not_found (void)
 static int
 has_library_ext (const char *filename)
 {
-  char *        ext     = 0;
-  size_t        len;
+  char *       ext     = 0;
+  size_t       len;
 
   assert (filename);
 
@@ -1430,7 +1492,7 @@ has_library_ext (const char *filename)
 
   if (ext && ((streq (ext, archive_ext))
 #if defined(LT_MODULE_EXT)
-             || (streq (ext, shlib_ext))
+            || (streq (ext, shlib_ext))
 #endif
     ))
     {
@@ -1528,7 +1590,7 @@ lt_dlhandle
 lt_dlopenadvise (const char *filename, lt_dladvise advise)
 {
   lt_dlhandle  handle  = 0;
-  int          errors  = 0;
+  int          errors  = 0;
 
   /* Can't have symbols hidden and visible at the same time!  */
   if (advise
@@ -1545,9 +1607,9 @@ lt_dlopenadvise (const char *filename, lt_dladvise advise)
       || has_library_ext (filename))
     {
       /* Just incase we missed a code path in try_dlopen() that reports
-         an error, but forgot to reset handle... */
+        an error, but forgot to reset handle... */
       if (try_dlopen (&handle, filename, NULL, advise) != 0)
-        return 0;
+       return 0;
 
       return handle;
     }
@@ -1559,21 +1621,21 @@ lt_dlopenadvise (const char *filename, lt_dladvise advise)
       errors += try_dlopen (&handle, filename, archive_ext, advise);
 
       /* 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.  */
+        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;
+       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.  */
+        with the current error message.  */
       if (handle || ((errors > 0) && !file_not_found ()))
-        return handle;
+       return handle;
 #endif
     }
 
@@ -2170,9 +2232,9 @@ lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
     {
       interface_id->id_string = lt__strdup (id_string);
       if (!interface_id->id_string)
-        FREE (interface_id);
+       FREE (interface_id);
       else
-        interface_id->iface = iface;
+       interface_id->iface = iface;
     }
 
   return (lt_dlinterface_id) interface_id;
index aa38c75df9586726228f9c36e25e2e867021d9e7..aa579d4caee3572fc8ac232442cdeec7869bd705 100644 (file)
@@ -3222,6 +3222,7 @@ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p'
 
 # Transform an extracted symbol line into symbol name and symbol address
 lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -3375,6 +3376,9 @@ _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
 _LT_DECL([global_symbol_to_c_name_address],
     [lt_cv_sys_global_symbol_to_c_name_address], [1],
     [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
 ]) # _LT_CMD_GLOBAL_SYMBOLS
 
 
diff --git a/tests/TODO b/tests/TODO
new file mode 100644 (file)
index 0000000..6e6f065
--- /dev/null
@@ -0,0 +1,7 @@
+Please write the following testcases and submit to libtool-patches@gnu.org:
+
+ - ensure each libtool library 'originator' is tried.
+ - check that passing NULL as the 'originator' correctly loads all
+   preloaded modules originating from "self" (program itself).
+ - test whether a preloaded library will open without the matching
+   .la file.
diff --git a/tests/need_lib_prefix.at b/tests/need_lib_prefix.at
new file mode 100644 (file)
index 0000000..d9cf769
--- /dev/null
@@ -0,0 +1,179 @@
+# need-lib-prefix.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.
+####
+
+AT_SETUP([enforced lib prefix])
+AT_KEYWORDS([libltdl libtool])
+
+AT_DATA([main.c],
+[[#include <ltdl.h>
+#include <stdio.h>
+
+typedef int fun (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_dlhandle handle;
+
+  handle = lt_dlopen (filename);
+  if (!handle)
+    {
+      fprintf (stderr, "can't open the module %s!\n", filename);
+      complain ("error was");
+    }
+
+  return handle;
+}
+
+static int
+moduletest (lt_dlhandle handle)
+{
+  const lt_dlinfo *info = lt_dlgetinfo (handle);
+  fun *f = (fun *) lt_dlsym (handle, "f");
+  int *v = (int *) lt_dlsym (handle, "i");
+
+  if (!f)
+    {
+      complain ("function `f' not found");
+      return 1;
+    }
+  if (!v)
+    {
+      complain ("variable `i' not found");
+      return 1;
+    }
+  printf ("%s: %d\n", info->name, f (*v));
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  lt_dlhandle handle;
+
+  LTDL_SET_PRELOADED_SYMBOLS();
+
+  if (lt_dlinit() != 0)
+    {
+      fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
+      return 1;
+    }
+
+  if (lt_dlpreload_open (0, moduletest) != 0)
+    complain ("error during preloading");
+
+  if (lt_dlexit () != 0)
+    complain ("error during exit");
+
+  return (errors != 0);
+}
+]])
+
+AT_DATA([foo1.c],
+[[#define f foo1_LTX_f
+#define i foo1_LTX_i
+#ifdef __cplusplus
+extern "C" {
+#endif
+int f (int x) { return x / 3; }
+int i = 7;
+#ifdef __cplusplus
+}
+#endif
+]])
+
+AT_DATA([foo2.c],
+[[#define f libfoo2_LTX_f
+#define i libfoo2_LTX_i
+#ifdef __cplusplus
+extern "C" {
+#endif
+int f (int x) { return (x * x) / 10; }
+int i = 6;
+#ifdef __cplusplus
+}
+#endif
+]])
+
+AT_DATA([expout],
+[[libfoo1: 2
+libfoo2: 3
+]])
+
+: ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
+: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
+
+CPPFLAGS="$CPPFLAGS $LTDLINCL"
+LDFLAGS="$LDFLAGS"
+
+# Create our own libtool, forcing need_lib_prefix setting
+sed 's,^\(need_lib_prefix\)=.*$,\1=unknown,' $LIBTOOL > ./libtool
+LIBTOOL="$SHELL ./libtool"
+
+# Installation directory:
+instdir=`pwd`/_inst
+
+$CC $CPPFLAGS $CFLAGS -c main.c
+for file in foo1 foo2; do
+  $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c $file.c
+done
+
+AT_CHECK([$LIBTOOL --mode=link $CC -module -avoid-version $CFLAGS $LDFLAGS -o foo1.la foo1.lo -rpath $instdir/lib],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC -module -avoid-version $CFLAGS $LDFLAGS -o libfoo2.la foo2.lo -rpath $instdir/lib],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main main.$OBJEXT -dlpreopen foo1.la -dlpreopen libfoo2.la $LIBLTDL],
+          [], [ignore], [ignore])
+
+LT_AT_NOINST_EXEC_CHECK([./main], [-dlopen foo1.la -dlopen libfoo2.la],
+             [], [expout], [])
+
+# Install the libraries.
+mkdir $instdir
+mkdir $instdir/lib
+$LIBTOOL --mode=install cp foo1.la $instdir/lib/foo1.la
+$LIBTOOL --mode=install cp libfoo2.la $instdir/lib/libfoo2.la
+
+# Install the binary
+mkdir $instdir/bin
+$LIBTOOL --mode=install cp main $instdir/bin/main
+
+LT_AT_EXEC_CHECK([$instdir/bin/main], [], [expout], [])
+
+AT_CLEANUP