From: Alexandre Oliva Date: Sat, 9 Jan 1999 20:05:55 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: automake_1-4~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e842493250c6d947049aa265513511ae6a720bdc;p=thirdparty%2Flibtool.git *** empty log message *** --- diff --git a/ChangeLog b/ChangeLog index 7ee149074..57599157d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,7 +11,11 @@ * 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 diff --git a/libltdl/configure.in b/libltdl/configure.in index ed623ef65..a60e8e430 100644 --- a/libltdl/configure.in +++ b/libltdl/configure.in @@ -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 || diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index 242416186..0855f03fb 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -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 #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 #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; } diff --git a/mdemo/main.c b/mdemo/main.c index f72dcf0c6..cfc0d1433 100644 --- a/mdemo/main.c +++ b/mdemo/main.c @@ -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; }