]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
*** empty log message ***
authorAlexandre Oliva <oliva@dcc.unicamp.br>
Sat, 9 Jan 1999 20:05:55 +0000 (20:05 +0000)
committerThomas Tanner <tanner@gmx.de>
Sat, 9 Jan 1999 20:05:55 +0000 (20:05 +0000)
ChangeLog
libltdl/configure.in
libltdl/ltdl.c
mdemo/main.c

index 7ee14907422abc96cef77f27c5bcd1aca8551709..57599157d49732b12c75b8848102bf5cbffa1a07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * demo/configure.in: check for libm, string.h and math.h
        * mdemo/configure.in: likewise
        * depdemo/configure.in: check for libm and math.h
-       * libltdl/ltdl.c: check for buffer overflows
+       * libltdl/configure.in: check for dlerror
+       * libltdl/ltdl.c: check for buffer overflows, implemented
+         dlerror, fixed a severe bug which occured when opening 
+         non-libtool modules, dlopen with the flags GLOBAL and NOW
+       * mdemo/main.c: report the error using lt_dlerror()
        
 1999-01-07  Gary V. Vaughan  <gvaughan@oranda.demon.co.uk>
 
index ed623ef65d0c7a9b1f59d53b7d6be6550d5f526f..a60e8e430a0cd4f2a8fbfbf2fe2a0610acea5db7 100644 (file)
@@ -37,16 +37,24 @@ if test x"$libltdl_cv_dlpreopen" = x"yes"; then
 fi
 
 supported=yes
+test_dlerror=no
 LIBADD_DL=
-AC_CHECK_FUNCS(dlopen, AC_DEFINE(HAVE_LIBDL),
-[AC_CHECK_LIB(dl, dlopen, [AC_DEFINE(HAVE_LIBDL) LIBADD_DL="-ldl"],
- [AC_CHECK_LIB(dld, dld_link, [AC_DEFINE(HAVE_DLD) LIBADD_DL="-ldld"],
-   [AC_CHECK_FUNCS(shl_load, AC_DEFINE(HAVE_SHL_LOAD))]
+AC_CHECK_FUNCS(dlopen, [AC_DEFINE(HAVE_LIBDL) test_dlerror=yes],
+  [AC_CHECK_LIB(dl, dlopen, [AC_DEFINE(HAVE_LIBDL) LIBADD_DL="-ldl" test_dlerror=yes],
+    [AC_CHECK_LIB(dld, dld_link, [AC_DEFINE(HAVE_DLD) LIBADD_DL="-ldld"],
+      [AC_CHECK_FUNCS(shl_load, AC_DEFINE(HAVE_SHL_LOAD))]
+    )]
   )]
- )]
 )
 AC_SUBST(LIBADD_DL)
 
+if test "$test_dlerror" = yes; then
+ LIBS_SAVE="$LIBS"
+ LIBS="$LIBS $LIBADD_DL"
+ AC_CHECK_FUNCS(dlerror)
+ LIBS="$LIBS_SAVE"
+fi
+
 AM_SYS_SYMBOL_UNDERSCORE
 if test x"$USE_SYMBOL_UNDERSCORE" = xyes; then
   if test x"$ac_cv_func_dlopen" = xyes ||
index 242416186e84af42cb76441b434b5baf6162723d..0855f03fbfadf23a58bb808e6a2663dcc00f48df 100644 (file)
@@ -54,7 +54,17 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 #include "ltdl.h"
 
-static const char *last_error = "unknown error";
+static const char *unknown_error = "unknown error";
+static const char *not_supported_error = "dlopen support not available";
+static const char *file_not_found_error = "file not found";
+static const char *no_symbols_error = "no symbols defined";
+static const char *symbol_error = "symbol not found";
+static const char *memory_error = "not enough memory";
+static const char *invalid_handle_error = "invalid handle";
+static const char *buffer_overflow_error = "internal buffer overflow";
+static const char *shutdown_error = "libraries already shutdown";
+
+static const char *last_error;
 
 typedef struct lt_dltype_t {
        struct lt_dltype_t *next;
@@ -163,13 +173,27 @@ strrchr(str, ch)
 # include <dlfcn.h>
 #endif
 
-#ifdef RTLD_LAZY       
-#  define DLOPEN_MODE  RTLD_LAZY
+#if ! HAVE_DLERROR     /* not all platforms have dlerror() */
+#define        dlerror()       unknown_error
+#endif
+
+#if RTDL_GLOBAL
+# define LTDL_GLOBAL   RTDL_GLOBAL
+#else
+# if DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+#if RTDL_NOW
+# define LTDL_NOW      RTDL_NOW
 #else
-# ifdef DL_LAZY
-#  define DLOPEN_MODE  DL_LAZY
+# if DL_NOW
+#  define LTDL_NOW     DL_NOW
 # else
-#  define DLOPEN_MODE  1
+#  define LTDL_NOW     0
 # endif
 #endif
 
@@ -190,15 +214,23 @@ dl_open (handle, filename)
        lt_dlhandle handle;
        const char *filename;
 {
-       handle->handle = dlopen(filename, DLOPEN_MODE);
-       return !(handle->handle);
+       handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_NOW);
+       if (!handle->handle) {
+               last_error = dlerror();
+               return 1;
+       }
+       return 0;
 }
 
 static int
 dl_close (handle)
        lt_dlhandle handle;
 {
-       return dlclose(handle->handle);
+       if (dlclose(handle->handle) != 0) {
+               last_error = dlerror();
+               return 1;
+       }
+       return 0;
 }
 
 static lt_ptr_t
@@ -206,7 +238,11 @@ dl_sym (handle, symbol)
        lt_dlhandle handle;
        const char *symbol;
 {
-       return dlsym(handle->handle, symbol);
+       lt_ptr_t address = dlsym(handle->handle, symbol);
+       
+       if (!address) 
+               last_error = dlerror();
+       return address;
 }
 
 static
@@ -227,8 +263,6 @@ dl = { LT_DLTYPE_TOP, dl_init, dl_exit,
 #include <dl.h>
 #endif
 
-/* the following lines are (c) Tim Janik */
-
 /* some flags are missing on some systems, so we provide
  * harmless defaults.
  *
@@ -254,6 +288,7 @@ dl = { LT_DLTYPE_TOP, dl_init, dl_exit,
  * DYNAMIC_PATH           - Allow the loader to dynamically search for the library specified
  *                  by the path argument.
  */
+
 #ifndef        DYNAMIC_PATH
 #define        DYNAMIC_PATH    0
 #endif /* DYNAMIC_PATH */
@@ -282,14 +317,21 @@ shl_open (handle, filename)
 {
        handle->handle = shl_load (filename, OPT_BIND_FLAGS, 0L);
        /* the hp-docs say we should better abort() if errno==ENOSYM ;( */
-       return !(handle->handle);
+       if (!handle->handle) {
+               last_error = unknown_error;
+               return 1;
+       }
+       return 0;
 }
 
 static int
 shl_close (handle)
        lt_dlhandle handle;
 {
-       shl_unload((shl_t) (handle->handle));
+       if (shl_unload((shl_t) (handle->handle)) != 0) {
+               last_error = unknown_error;
+               return 1;
+       }
        return 0;
 }
 
@@ -298,12 +340,14 @@ shl_sym (handle, symbol)
        lt_dlhandle handle;
        const char *symbol;
 {
-       lt_ptr_t *sym;
+       lt_ptr_t address;
 
-       if (shl_findsym ((shl_t) (handle->handle), symbol,
-                       TYPE_UNDEFINED, &sym) || !(handle->handle) || !sym)
+       if (shl_findsym ((shl_t) (handle->handle), symbol, TYPE_UNDEFINED, 
+           &address) != 0 || !(handle->handle) || !address) {
+               last_error = unknown_error;
                return 0;
-       return sym;
+       }
+       return address;
 }
 
 static
@@ -337,8 +381,10 @@ dld_open (handle, filename)
        lt_dlhandle handle;
        const char *filename;
 {
-       if (dld_link(filename))
+       if (dld_link(filename) != 0) {
+               last_error = unknown_error;
                return 1;
+       }
        handle->handle = strdup(filename);
        return 0;
 }
@@ -347,7 +393,10 @@ static int
 dld_close (handle)
        lt_dlhandle handle;
 {
-       dld_unlink_by_file((char*)(handle->handle), 1);
+       if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
+               last_error = unknown_error;
+               return 1;
+       }
        free(handle->filename);
        return 0;
 }
@@ -357,7 +406,11 @@ dld_sym (handle, symbol)
        lt_dlhandle handle;
        const char *symbol;
 {
-       return dld_get_func(symbol);
+       lt_ptr_t address = dld_get_func(symbol);
+       
+       if (!address) 
+               last_error = unknown_error;
+       return address;
 }
 
 static
@@ -394,14 +447,21 @@ wll_open (handle, filename)
        const char *filename;
 {
        handle->handle = LoadLibrary(filename);
-       return !(handle->handle);
+       if (!handle->handle) {
+               last_error = unknown_error;
+               return 1;
+       }
+       return 0;
 }
 
 static int
 wll_close (handle)
        lt_dlhandle handle;
 {
-       FreeLibrary(handle->handle);
+       if (FreeLibrary(handle->handle) != 0) {
+               last_error = unknown_error;
+               return 1;
+       }
        return 0;
 }
 
@@ -410,7 +470,11 @@ wll_sym (handle, symbol)
        lt_dlhandle handle;
        const char *symbol;
 {
-       return GetProcAddress(handle->handle, symbol);
+       lt_ptr_t address = GetProcAddress(handle->handle, symbol);
+       
+       if (!address) 
+               last_error = unknown_error;
+       return address;
 }
 
 static
@@ -429,8 +493,8 @@ wll = { LT_DLTYPE_TOP, wll_init, wll_exit,
 
 struct lt_dlsymlist
 {
-  char *name;
-  lt_ptr_t address;
+       char *name;
+       lt_ptr_t address;
 };
 
 static struct lt_dlsymlist *preloaded_symbols;
@@ -454,16 +518,23 @@ dldpre_open (handle, filename)
 {
        struct lt_dlsymlist *s = preloaded_symbols;
 
-       if (!s)
+       if (!filename) {
+               last_error = file_not_found_error;
                return 1;
-
+       }
+       if (!s) {
+               last_error = no_symbols_error;
+               return 1;
+       }
        while (s->name) {
                if (!s->address && !strcmp(s->name, filename))
                        break;
                s++;
        }
-       if (!s->name)
+       if (!s->name) {
+               last_error = file_not_found_error;
                return 1;
+       }
        handle->handle = s;
        return 0;
 }
@@ -482,12 +553,9 @@ dldpre_sym (handle, symbol)
 {
        struct lt_dlsymlist *s = (struct lt_dlsymlist*)(handle->handle);
 
-       if (!s)
-               return 0;
-
 #if NEED_USCORE
        /* lt_dlsym will have prepended a `_', but we don't need it */
-       ++symbol;
+       symbol++;
 #endif
        s++;
        while (s->address) {
@@ -495,6 +563,7 @@ dldpre_sym (handle, symbol)
                        return s->address;
                s++;
        }
+       last_error = symbol_error;
        return 0;
 }
 
@@ -535,8 +604,11 @@ lt_dlinit ()
                        typecount++;
                }
        }
-       if (typecount == 0)
+       if (typecount == 0) {
+               last_error = not_supported_error;
                return 1;
+       }
+       last_error = 0;
        initialized = 1;
        return 0;
 }
@@ -561,8 +633,10 @@ lt_dlexit ()
        lt_dltype type = types;
        int     errors;
        
-       if (!initialized)
-               return 1;       /* already deinitialized */     
+       if (!initialized) {
+               last_error = shutdown_error;
+               return 1;
+       }
        if (initialized != 1) { /* shut down only at last call. */
                initialized--;
                return 0;
@@ -605,6 +679,7 @@ tryall_dlopen (handle, filename)
 {
        lt_dlhandle cur;
        lt_dltype type = types;
+       const char *saved_error = last_error;
        
        /* check whether the module was already opened */
        cur = handles;
@@ -622,9 +697,12 @@ tryall_dlopen (handle, filename)
                        break;
                type = type->next;
        }
+       if (!type)
+               return 1;
        (*handle)->type = type;
        (*handle)->filename = strdup(filename);
-       return !(type);
+       last_error = saved_error;
+       return 0;
 }
 
 #undef MAX_FILENAME
@@ -684,17 +762,19 @@ lt_dlopen (filename)
 {
        lt_dlhandle handle;
        FILE    *file;
-       char    dir[MAX_FILENAME];
-       char    tmp[MAX_FILENAME];
+       char    dir[MAX_FILENAME], tmp[MAX_FILENAME];
        const char *basename, *ext, *search_path;
+       const char *saved_error = last_error;
        
        basename = strrchr(filename, '/');
        if (basename)
                basename++;
        else
                basename = filename;
-       if (basename - filename >= MAX_FILENAME)
+       if (basename - filename >= MAX_FILENAME) {
+               last_error = buffer_overflow_error;
                return 0;
+       }
        strncpy(dir, filename, basename - filename);
        dir[basename - filename] = '\0';
        search_path = getenv("LTDL_LIBRARY_PATH"); /* get the search path */
@@ -718,14 +798,18 @@ lt_dlopen (filename)
                        while (!file && p) {
                                next = strchr(p, ':');
                                if (next) {
-                                       if (next - p + 1 >= MAX_FILENAME)
+                                       if (next - p + 1 >= MAX_FILENAME) {
+                                               last_error = buffer_overflow_error;
                                                return 0;
+                                       }
                                        strncpy(dir, p, next - p);
                                        dir[next - p] = '\0';
                                        p = next+1;
                                } else {
-                                       if (strlen(p)+1 >= MAX_FILENAME)
+                                       if (strlen(p)+1 >= MAX_FILENAME) {
+                                               last_error = buffer_overflow_error;
                                                return 0;
+                                       }
                                        strcpy(dir, p);
                                        p = 0;
                                }
@@ -739,8 +823,10 @@ lt_dlopen (filename)
                                }
                        }
                }
-               if (!file)
+               if (!file) {
+                       last_error = file_not_found_error;
                        return 0;
+               }
                while (!feof(file)) {
                        if (!fgets(tmp, MAX_FILENAME, file))
                                break;
@@ -760,15 +846,20 @@ lt_dlopen (filename)
                /* FIXME: preload required libraries */
                
                handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t));
-               if (!handle)
+               if (!handle) {
+                       last_error = memory_error;
                        return 0;
+               }
                if (find_module(&handle, dir, libdir, dlname, old_name)) {
                        free(handle);
+                       last_error = file_not_found_error;
                        return 0;
                }
                /* extract the module name from the file name */
-               if (strlen(basename) >= MAX_FILENAME)
+               if (strlen(basename) >= MAX_FILENAME) {
+                       last_error = buffer_overflow_error;
                        return 0;
+               }
                strcpy(tmp, basename);
                tmp[ext - basename] = '\0';
                /* canonicalize the module name */
@@ -779,10 +870,11 @@ lt_dlopen (filename)
        } else {
                /* not a libtool module */
                handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t));
-               if (!handle)
+               if (!handle) {
+                       last_error = memory_error;
                        return 0;
-                       
-               if (tryall_dlopen(*handle, filename)) {
+               }
+               if (tryall_dlopen(&handle, filename)) {
                        int     error = 1;
                        
                        if (!*dir && search_path) {
@@ -795,14 +887,18 @@ lt_dlopen (filename)
                                while (error && p) {
                                        next = strchr(p, ':');
                                        if (next) {
-                                               if (next - p + 1 >= MAX_FILENAME)
+                                               if (next - p + 1 >= MAX_FILENAME) {
+                                                       last_error = buffer_overflow_error;
                                                        return 0;
+                                               }
                                                strncpy(dir, p, next - p);
                                                dir[next - p] = '\0';
                                                p = next+1;
                                        } else {
-                                               if (strlen(p)+1 >= MAX_FILENAME)
+                                               if (strlen(p)+1 >= MAX_FILENAME) {
+                                                       last_error = buffer_overflow_error;
                                                        return 0;
+                                               }
                                                strcpy(dir, p);
                                                p = 0;
                                        }
@@ -812,12 +908,13 @@ lt_dlopen (filename)
                                        if (strlen(dir)+strlen(basename) < MAX_FILENAME) {
                                                strcpy(tmp, dir);
                                                strcat(tmp, basename);
-                                               error = tryall_dlopen(*handle, tmp);
+                                               error = tryall_dlopen(&handle, tmp);
                                        }
                                }
                        }
                        if (error) {
                                free(handle);
+                               last_error = file_not_found_error;
                                return 0;
                        }
                }
@@ -826,6 +923,7 @@ lt_dlopen (filename)
        handle->usage = 1;
        handle->next = handles;
        handles = handle;
+       last_error = saved_error;
        return handle;
 }
 
@@ -841,8 +939,10 @@ lt_dlclose (handle)
                last = cur;
                cur = cur->next;
        }
-       if (!cur)       
-               return 1; /* invalid handle */
+       if (!cur) {
+               last_error = invalid_handle_error;
+               return 1;
+       }
        handle->usage--;
        if (!handle->usage) {
                int     error;
@@ -871,6 +971,10 @@ lt_dlsym (handle, symbol)
        char    sym[MAX_SYMBOL_LENGTH];
        lt_ptr_t address;
 
+       if (strlen(symbol) >= MAX_SYMBOL_LENGTH) {
+               last_error = buffer_overflow_error;
+               return 0;
+       }
 #ifdef NEED_USCORE
        if (handle->name && strlen(handle->name) < MAX_SYMBOL_LENGTH-6) {
                /* this is a libtool module */
@@ -895,8 +999,6 @@ lt_dlsym (handle, symbol)
 #ifdef NEED_USCORE
        /* prefix symbol with leading underscore */
        strcpy(sym, "_");
-       if (strlen(symbol) >= MAX_SYMBOL_LENGTH)
-               return 0;
        strcat(sym, symbol);
        return handle->type->find_sym(handle, sym);
 #else
@@ -907,5 +1009,8 @@ lt_dlsym (handle, symbol)
 const char *
 lt_dlerror ()
 {
-       return last_error;
+       const char *error = last_error;
+       
+       last_error = 0;
+       return error;
 }
index f72dcf0c6024cc1a4e11a3d931ae1a98de57f3da..cfc0d14337192270e856d0e1135975bb85afa640 100644 (file)
@@ -46,6 +46,7 @@ test_dl (char *filename)
   handle = lt_dlopen(filename);
   if (!handle) {
     fprintf (stderr, "can't open the module %s!\n", filename);
+    fprintf (stderr, "error was: %s\n", lt_dlerror());
     return 1;
   }
   phello = lt_dlsym(handle, "hello");  
@@ -100,7 +101,7 @@ main (int argc, char **argv)
   }
 
   if (lt_dlinit() != 0) {
-    fprintf (stderr, "dlopen not supported\n");
+    fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
     return 1;
   }