aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-10 07:53:51 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-10 07:53:51 +0000
commit0e559128637967a3f5475434c35cde9028d2fce2 (patch)
tree16d095c004e03e8ff643879cc387ac046ccb2192
parent9e7c8297b8a16f1d042b68915cc1b65247c35f8a (diff)
Update to libtool multi-language branch
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/FSF@36292 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libjava/libltdl/Makefile.am2
-rw-r--r--libjava/libltdl/configure.in351
-rw-r--r--libjava/libltdl/ltdl.c1301
-rw-r--r--libjava/libltdl/ltdl.h192
4 files changed, 1017 insertions, 829 deletions
diff --git a/libjava/libltdl/Makefile.am b/libjava/libltdl/Makefile.am
index a1df9fc37b7..1f01d23eb52 100644
--- a/libjava/libltdl/Makefile.am
+++ b/libjava/libltdl/Makefile.am
@@ -14,7 +14,7 @@ noinst_LTLIBRARIES = libltdlc.la
endif
libltdl_la_SOURCES = ltdl.c
-libltdl_la_LDFLAGS = -version-info 1:2:1
+libltdl_la_LDFLAGS = -no-undefined -version-info 2:0:2
libltdl_la_LIBADD = $(LIBADD_DL)
libltdlc_la_SOURCES = ltdl.c
diff --git a/libjava/libltdl/configure.in b/libjava/libltdl/configure.in
index 2cf4149e2f3..8192e539ba1 100644
--- a/libjava/libltdl/configure.in
+++ b/libjava/libltdl/configure.in
@@ -2,6 +2,13 @@ dnl Process this file with autoconf to create configure.
AC_INIT(ltdl.c)
+dnl We shouldn't be using these internal macros of autoconf,
+dnl but CONFIG_AUX_DIR($with_auxdir) breaks automake.
+AC_ARG_WITH(auxdir,
+[ --with-auxdir=DIR path to autoconf auxiliary files],
+[AC_CONFIG_AUX_DIRS($with_auxdir)],
+[AC_CONFIG_AUX_DIR_DEFAULT])
+
if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then
if test -f ${srcdir}/ltconfig && test -f ${srcdir}/ltmain.sh; then
# if libltdl is libtoolized, it is assumed to be stand-alone and
@@ -14,355 +21,19 @@ if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then
fi
fi
-AM_INIT_AUTOMAKE(libltdl,1.0,-)
+AM_INIT_AUTOMAKE(libltdl,1.1,-)
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
AC_PROG_CC
AC_C_CONST
AC_C_INLINE
+
+AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
-AC_ARG_ENABLE(ltdl-install,
-[ --enable-ltdl-install install libltdl])
-
-AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno)
-AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)
-
-dnl Read the libtool configuration
-rm -f conftest
-./libtool --config > conftest
-. ./conftest
-rm -f conftest
-
-AC_CACHE_CHECK([which extension is used for shared libraries],
- libltdl_cv_shlibext, [dnl
-(
- last=
- for spec in $library_names_spec; do
- last="$spec"
- done
-changequote(, )
- echo "$last" | sed 's/\[.*\]//;s/^[^.]*//;s/\$.*$//;s/\.$//' > conftest
-changequote([, ])
-)
-libltdl_cv_shlibext=`cat conftest`
-rm -f conftest
-])
-if test -n "$libltdl_cv_shlibext"; then
- AC_DEFINE_UNQUOTED(LTDL_SHLIB_EXT, "$libltdl_cv_shlibext",
- [Define to the extension used for shared libraries, say, ".so". ])
-fi
-
-AC_CACHE_CHECK([which variable specifies run-time library path],
- libltdl_cv_shlibpath_var, [libltdl_cv_shlibpath_var="$shlibpath_var"])
-if test -n "$libltdl_cv_shlibpath_var"; then
- AC_DEFINE_UNQUOTED(LTDL_SHLIBPATH_VAR, "$libltdl_cv_shlibpath_var",
- [Define to the name of the environment variable that determines the dynamic library search path. ])
-fi
-
-AC_CACHE_CHECK([for objdir],
- libltdl_cv_objdir, [libltdl_cv_objdir="$objdir"])
-test -z "$libltdl_cv_objdir" && libltdl_cv_objdir=".libs"
-AC_DEFINE_UNQUOTED(LTDL_OBJDIR, "$libltdl_cv_objdir/",
- [Define to the sub-directory in which libtool stores uninstalled libraries. ])
-
-AC_HEADER_STDC
-AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dlfcn.h dl.h dld.h)
-AC_CHECK_HEADERS(string.h strings.h, break)
-AC_CHECK_FUNCS(strchr index, break)
-AC_CHECK_FUNCS(strrchr rindex, break)
-
-AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen],
- libltdl_cv_preloaded_symbols, [dnl
- if test -n "$global_symbol_pipe"; then
- libltdl_cv_preloaded_symbols=yes
- else
- libltdl_cv_preloaded_symbols=no
- fi
-])
-if test x"$libltdl_cv_preloaded_symbols" = x"yes"; then
- AC_DEFINE(HAVE_PRELOADED_SYMBOLS, 1,
- [Define if libtool can extract symbol lists from object files. ])
-fi
-
-LIBADD_DL=
-AC_CHECK_LIB(dl, dlopen, [AC_DEFINE(HAVE_LIBDL, 1) LIBADD_DL="-ldl"],
-[AC_CHECK_FUNC(dlopen, [AC_DEFINE(HAVE_LIBDL, 1)])])
-AC_CHECK_FUNC(shl_load, [AC_DEFINE(HAVE_SHL_LOAD, 1)],
-[AC_CHECK_LIB(dld, shl_load, [AC_DEFINE(HAVE_SHL_LOAD, 1) LIBADD_DL="$LIBADD_DL -ldld"])])
-AC_CHECK_LIB(dld, dld_link, [AC_DEFINE(HAVE_DLD, 1)dnl
-test "x$ac_cv_lib_dld_shl_load" = yes || LIBADD_DL="$LIBADD_DL -ldld"])
-AC_SUBST(LIBADD_DL)
-
-if test "x$ac_cv_func_dlopen" = xyes || test "x$ac_cv_lib_dl_dlopen" = xyes; then
- LIBS_SAVE="$LIBS"
- LIBS="$LIBS $LIBADD_DL"
- AC_CHECK_FUNCS(dlerror)
- LIBS="$LIBS_SAVE"
-fi
-
-dnl Check for command to grab the raw symbol name followed
-dnl by C symbol name from nm.
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_PROG_NM])dnl
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-AC_MSG_CHECKING([command to parse $NM output])
-AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
-[# These are sane defaults that work on at least a few old systems.
-# {They come from Ultrix. What could be older than Ultrix?!! ;)}
-
-changequote(,)dnl
-# Character class describing NM global symbol codes.
-ac_symcode='[BCDEGRST]'
-
-# Regexp to match symbols that can be accessed directly from C.
-ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-
-# Transform the above into a raw symbol and a C symbol.
-ac_symxfrm='\1 \2\3 \3'
-
-# Transform an extracted symbol line into a proper C declaration
-ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
-
-# Define system-specific variables.
-case "$host_os" in
-aix*)
- ac_symcode='[BCDT]'
- ;;
-cygwin* | mingw*)
- ac_symcode='[ABCDGISTW]'
- ;;
-hpux*)
- ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
- ;;
-irix*)
- ac_symcode='[BCDEGRST]'
- ;;
-solaris*)
- ac_symcode='[BDT]'
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
- ac_symcode='[ABCDGISTW]'
-fi
-changequote([,])dnl
-
-# Try without a prefix undercore, then with it.
-for ac_symprfx in "" "_"; do
-
- ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
-
- # Check to see that the pipe works correctly.
- ac_pipe_works=no
- rm -f conftest.$ac_ext
- cat > conftest.$ac_ext <<EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func;return 0;}
-EOF
-
- if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- ac_nlist=conftest.nm
-
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
-
- # Try sorting and uniquifying the output.
- if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
- mv -f "$ac_nlist"T "$ac_nlist"
- else
- rm -f "$ac_nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
- if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
- cat <<EOF > conftest.c
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-EOF
- # Now generate the symbol file.
- eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
-
- cat <<EOF >> conftest.c
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- lt_ptr_t address;
-}
-changequote(,)dnl
-lt_preloaded_symbols[] =
-changequote([,])dnl
-{
-EOF
- sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
- cat <<\EOF >> conftest.c
- {0, (lt_ptr_t) 0}
-};
-
-#ifdef __cplusplus
-}
-#endif
-EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- ac_save_LIBS="$LIBS"
- ac_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$no_builtin_flag"
- if AC_TRY_EVAL(ac_link) && test -s conftest; then
- ac_pipe_works=yes
- else
- echo "configure: failed program was:" >&AC_FD_CC
- cat conftest.c >&AC_FD_CC
- fi
- LIBS="$ac_save_LIBS"
- CFLAGS="$ac_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
- fi
- else
- echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
- fi
- else
- echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
- fi
- else
- echo "$progname: failed program was:" >&AC_FD_CC
- cat conftest.c >&AC_FD_CC
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$ac_pipe_works" = yes; then
- if test x"$ac_symprfx" = x"_"; then
- ac_cv_sys_symbol_underscore=yes
- else
- ac_cv_sys_symbol_underscore=no
- fi
- break
- else
- ac_cv_sys_global_symbol_pipe=
- fi
-done
-])
-
-ac_result=yes
-if test -z "$ac_cv_sys_global_symbol_pipe"; then
- ac_result=no
-fi
-AC_MSG_RESULT($ac_result)
-
-dnl does the compiler prefix global symbols with an underscore?
-AC_MSG_CHECKING([for _ prefix in compiled symbols])
-AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
-[ac_cv_sys_symbol_underscore=no
-cat > conftest.$ac_ext <<EOF
-void nm_test_func(){}
-int main(){nm_test_func;return 0;}
-EOF
-if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- ac_nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
- # See whether the symbols have a leading underscore.
- if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
- ac_cv_sys_symbol_underscore=yes
- else
- if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
- :
- else
- echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
- fi
- fi
- else
- echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
- fi
-else
- echo "configure: failed program was:" >&AC_FD_CC
- cat conftest.c >&AC_FD_CC
-fi
-rm -rf conftest*
-])
-AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
-
-if test x"$ac_cv_sys_symbol_underscore" = xyes; then
- if test x"$ac_cv_func_dlopen" = xyes ||
- test x"$ac_cv_lib_dl_dlopen" = xyes ; then
- AC_CACHE_CHECK([whether we have to add an underscore for dlsym],
- libltdl_cv_need_uscore, [dnl
- AC_TRY_RUN([
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LTDL_GLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LTDL_GLOBAL DL_GLOBAL
-# else
-# define LTDL_GLOBAL 0
-# endif
-#endif
-
-/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LTDL_LAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LTDL_LAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LTDL_LAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LTDL_LAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LTDL_LAZY_OR_NOW DL_NOW
-# else
-# define LTDL_LAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-fnord() { int i=42;}
-main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
- if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
- if(ptr1 && !ptr2) { dlclose(self); exit(0); } } exit(1); }
-], libltdl_cv_need_uscore=no, libltdl_cv_need_uscore=yes,
- libltdl_cv_need_uscore=cross
-)])
- fi
-fi
-
-if test x"$libltdl_cv_need_uscore" = xyes; then
- AC_DEFINE(NEED_USCORE, 1,
- [Define if dlsym() requires a leading underscode in symbol names. ])
-fi
+AC_LIB_LTDL
dnl Output the makefile
AC_OUTPUT(Makefile)
diff --git a/libjava/libltdl/ltdl.c b/libjava/libltdl/ltdl.c
index 4d75e02e51f..4bcf3ed446b 100644
--- a/libjava/libltdl/ltdl.c
+++ b/libjava/libltdl/ltdl.c
@@ -1,27 +1,28 @@
/* ltdl.c -- system independent dlopen wrapper
- Copyright (C) 1998-1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Originally by Thomas Tanner <tanner@ffii.org>
This file is part of GNU Libtool.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
+modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
-As a special exception to the GNU Library General Public License,
-if you distribute this file as part of a program that uses GNU libtool
-to create libraries and programs, you may include it under the same
+As a special exception to the GNU Lesser General Public License,
+if you distribute this file as part of a program or library that
+is built using GNU libtool, you may include it under the same
distribution terms that you use for the rest of that program.
This library 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
-Library General Public License for more details.
+Lesser General Public License for more details.
-You should have received a copy of the GNU Library General Public
+You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
+
*/
#define _LTDL_COMPILE_
@@ -60,6 +61,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
#include "ltdl.h"
+#ifdef DLL_EXPORT
+# define LTDL_GLOBAL_DATA __declspec(dllexport)
+#else
+# define LTDL_GLOBAL_DATA
+#endif
+
/* max. filename length */
#ifndef LTDL_FILENAME_MAX
#define LTDL_FILENAME_MAX 1024
@@ -81,56 +88,57 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
/* This accounts for the _LTX_ separator */
#define LTDL_SYMBOL_OVERHEAD 5
+/* NOTE: typedefed in ltdl.h
+ This structure is used for the list of registered loaders. */
+struct lt_dlloader_t {
+ struct lt_dlloader_t *next;
+ const char *loader_name; /* identifying name for each loader */
+ const char *sym_prefix; /* prefix for symbols */
+ lt_module_open_t *module_open;
+ lt_module_close_t *module_close;
+ lt_find_sym_t *find_sym;
+ lt_dlloader_exit_t *dlloader_exit;
+ lt_dlloader_data_t dlloader_data;
+};
+
+typedef struct lt_dlhandle_t {
+ struct lt_dlhandle_t *next;
+ lt_dlloader_t *loader; /* dlopening interface */
+ lt_dlinfo info;
+ int depcount; /* number of dependencies */
+ lt_dlhandle *deplibs; /* dependencies */
+ lt_module_t module; /* system module handle */
+ lt_ptr_t system; /* system specific data */
+ lt_ptr_t app_private; /* application private data */
+} lt_dlhandle_t;
+
static const char objdir[] = LTDL_OBJDIR;
#ifdef LTDL_SHLIB_EXT
static const char shlib_ext[] = LTDL_SHLIB_EXT;
#endif
+#ifdef LTDL_SYSSEARCHPATH
+static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
+#endif
-static const char unknown_error[] = "unknown error";
-static const char dlopen_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 cannot_open_error[] = "can't open the module";
-static const char cannot_close_error[] = "can't close the module";
-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[] = "library already shutdown";
-
-#ifndef HAVE_PRELOADED_SYMBOLS
-/* If libtool won't define it, we'd better do */
-const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+/* Extract the diagnostic strings from the error table macro in the same
+ order as the enumberated indices in ltdl.h. */
+#define LTDL_ERROR(name, diagnostic) (diagnostic),
+static const char *ltdl_error_strings[] = {
+ ltdl_error_table
+ 0
+};
+#undef LTDL_ERROR
+
+#ifdef __STDC__
+# define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_##name]
+#else
+# define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_/**/name]
#endif
static const char *last_error = 0;
-lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
-void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
-
-typedef struct lt_dltype_t {
- struct lt_dltype_t *next;
- const char *sym_prefix; /* prefix for symbols */
- int (*mod_init) LTDL_PARAMS((void));
- int (*mod_exit) LTDL_PARAMS((void));
- int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
- int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
- lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
-} lt_dltype_t;
-
-#define LTDL_TYPE_TOP 0
-
-typedef struct lt_dlhandle_t {
- struct lt_dlhandle_t *next;
- lt_dltype_t *type; /* dlopening interface */
- char *filename; /* file name */
- char *name; /* module name */
- int usage; /* usage */
- int depcount; /* number of dependencies */
- lt_dlhandle *deplibs; /* dependencies */
- lt_ptr_t handle; /* system handle */
- lt_ptr_t system; /* system specific data */
-} lt_dlhandle_t;
+LTDL_GLOBAL_DATA lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
+LTDL_GLOBAL_DATA void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
#undef strdup
#define strdup xstrdup
@@ -149,6 +157,32 @@ strdup(str)
return tmp;
}
+#if ! HAVE_STRCMP
+
+#undef strcmp
+#define strcmp xstrcmp
+
+static inline int
+strcmp (str1, str2)
+ const char *str1;
+ const char *str2;
+{
+ if (str1 == str2)
+ return 0;
+ if (str1 == 0)
+ return -1;
+ if (str2 == 0)
+ return 1;
+
+ for (;*str1 && *str2; str1++, str2++)
+ if (*str1 != *str2)
+ break;
+
+ return (int)(*str1 - *str2);
+}
+#endif
+
+
#if ! HAVE_STRCHR
# if HAVE_INDEX
@@ -206,7 +240,11 @@ strrchr(str, ch)
#endif
-#if HAVE_LIBDL
+/* The Cygwin dlopen implementation prints a spurious error message to
+ stderr if its call to LoadLibrary() fails for any reason. We can
+ mitigate this by not using the Cygwin implementation, and falling
+ back to our own LoadLibrary() wrapper. */
+#if HAVE_LIBDL && !defined(__CYGWIN__)
/* dynamic linking with dlopen/dlsym */
@@ -246,44 +284,32 @@ strrchr(str, ch)
# endif
#endif
-static int
-sys_dl_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dl_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dl_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_dl_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
- handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
- if (!handle->handle) {
+ lt_module_t module = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
+ if (!module) {
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = cannot_open_error;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
#endif
- return 1;
}
- return 0;
+ return module;
}
static int
-sys_dl_close (handle)
- lt_dlhandle handle;
+sys_dl_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
{
- if (dlclose(handle->handle) != 0) {
+ if (dlclose(module) != 0) {
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = cannot_close_error;
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
#endif
return 1;
}
@@ -291,34 +317,29 @@ sys_dl_close (handle)
}
static lt_ptr_t
-sys_dl_sym (handle, symbol)
- lt_dlhandle handle;
+sys_dl_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
const char *symbol;
{
- lt_ptr_t address = dlsym(handle->handle, symbol);
+ lt_ptr_t address = dlsym(module, symbol);
if (!address)
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
#endif
return address;
}
-static
-lt_dltype_t
-#ifdef NEED_USCORE
-sys_dl = { LTDL_TYPE_TOP, "_", sys_dl_init, sys_dl_exit,
- sys_dl_open, sys_dl_close, sys_dl_sym };
-#else
-sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
- sys_dl_open, sys_dl_close, sys_dl_sym };
-#endif
-
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_dl
-
+static struct lt_user_dlloader sys_dl = {
+# ifdef NEED_USCORE
+ "_",
+# else
+ 0,
+# endif
+ sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
#endif
#if HAVE_SHL_LOAD
@@ -364,168 +385,81 @@ sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
#define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
-static int
-sys_shl_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_shl_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_shl_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_shl_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
- handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
- if (!handle->handle) {
- last_error = cannot_open_error;
- return 1;
+ lt_module_t module = shl_load(filename, LTDL_BIND_FLAGS, 0L);
+ if (!module) {
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
}
- return 0;
+ return module;
}
static int
-sys_shl_close (handle)
- lt_dlhandle handle;
+sys_shl_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
{
- if (shl_unload((shl_t) (handle->handle)) != 0) {
- last_error = cannot_close_error;
+ if (shl_unload((shl_t) (module)) != 0) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
}
static lt_ptr_t
-sys_shl_sym (handle, symbol)
- lt_dlhandle handle;
+sys_shl_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
const char *symbol;
{
lt_ptr_t address;
- if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
+ if (module && shl_findsym((shl_t*) &module,
symbol, TYPE_UNDEFINED, &address) == 0)
if (address)
return address;
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
-static
-lt_dltype_t
-sys_shl = { LTDL_TYPE_TOP, 0, sys_shl_init, sys_shl_exit,
- sys_shl_open, sys_shl_close, sys_shl_sym };
+static struct lt_user_dlloader
+sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 };
#undef LTDL_TYPE_TOP
#define LTDL_TYPE_TOP &sys_shl
#endif
-#if HAVE_DLD
-
-/* dynamic linking with dld */
-
-#if HAVE_DLD_H
-#include <dld.h>
-#endif
-
-static int
-sys_dld_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dld_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dld_open (handle, filename)
- lt_dlhandle handle;
- const char *filename;
-{
- handle->handle = strdup(filename);
- if (!handle->handle) {
- last_error = memory_error;
- return 1;
- }
- if (dld_link(filename) != 0) {
- last_error = cannot_open_error;
- lt_dlfree(handle->handle);
- return 1;
- }
- return 0;
-}
-
-static int
-sys_dld_close (handle)
- lt_dlhandle handle;
-{
- if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
- last_error = cannot_close_error;
- return 1;
- }
- lt_dlfree(handle->filename);
- return 0;
-}
-
-static lt_ptr_t
-sys_dld_sym (handle, symbol)
- lt_dlhandle handle;
- const char *symbol;
-{
- lt_ptr_t address = dld_get_func(symbol);
-
- if (!address)
- last_error = symbol_error;
- return address;
-}
-
-static
-lt_dltype_t
-sys_dld = { LTDL_TYPE_TOP, 0, sys_dld_init, sys_dld_exit,
- sys_dld_open, sys_dld_close, sys_dld_sym };
-
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_dld
-
-#endif
-
#ifdef _WIN32
/* dynamic linking for Win32 */
#include <windows.h>
-static int
-sys_wll_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_wll_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
/* Forward declaration; required to implement handle search below. */
static lt_dlhandle handles;
-static int
-sys_wll_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_wll_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
lt_dlhandle cur;
- char *searchname = NULL;
- char *ext = strrchr(filename, '.');
+ lt_module_t module;
+ char *searchname = 0;
+ char *ext;
+ char self_name_buf[MAX_PATH];
+
+ if (!filename) {
+ /* Get the name of main module */
+ *self_name_buf = 0;
+ GetModuleFileName(NULL, self_name_buf, sizeof(self_name_buf));
+ filename = ext = self_name_buf;
+ }
+ else ext = strrchr(filename, '.');
if (ext) {
/* FILENAME already has an extension. */
@@ -534,11 +468,15 @@ sys_wll_open (handle, filename)
/* Append a `.' to stop Windows from adding an
implicit `.dll' extension. */
searchname = (char*)lt_dlmalloc(2+ strlen(filename));
+ if (!searchname) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 0;
+ }
strcpy(searchname, filename);
strcat(searchname, ".");
}
-
- handle->handle = LoadLibrary(searchname);
+
+ module = LoadLibrary(searchname);
lt_dlfree(searchname);
/* libltdl expects this function to fail if it is unable
@@ -551,53 +489,50 @@ sys_wll_open (handle, filename)
find one. */
cur = handles;
while (cur) {
- if (!cur->handle) {
+ if (!cur->module) {
cur = 0;
break;
}
- if (cur->handle == handle->handle)
+ if (cur->module == module)
break;
cur = cur->next;
}
- if (cur || !handle->handle) {
- last_error = cannot_open_error;
- return 1;
+ if (cur || !module) {
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
+ return 0;
}
- return 0;
+ return module;
}
static int
-sys_wll_close (handle)
- lt_dlhandle handle;
+sys_wll_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
{
- if (FreeLibrary(handle->handle) == 0) {
- last_error = cannot_close_error;
+ if (FreeLibrary(module) == 0) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
}
static lt_ptr_t
-sys_wll_sym (handle, symbol)
- lt_dlhandle handle;
+sys_wll_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
const char *symbol;
{
- lt_ptr_t address = GetProcAddress(handle->handle, symbol);
+ lt_ptr_t address = GetProcAddress(module, symbol);
if (!address)
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return address;
}
-static
-lt_dltype_t
-sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
- sys_wll_open, sys_wll_close, sys_wll_sym };
-
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_wll
+static struct lt_user_dlloader
+sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 };
#endif
@@ -607,21 +542,9 @@ sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
#include <kernel/image.h>
-static int
-sys_bedl_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_bedl_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_bedl_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_bedl_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
image_id image = 0;
@@ -635,47 +558,101 @@ sys_bedl_open (handle, filename)
image = load_add_on(info.name);
}
if (image <= 0) {
- last_error = cannot_open_error;
- return 1;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
+ return 0;
}
- handle->handle = (void*) image;
- return 0;
+
+ return (lt_module_t) image;
}
static int
-sys_bedl_close (handle)
- lt_dlhandle handle;
+sys_bedl_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
{
- if (unload_add_on((image_id)handle->handle) != B_OK) {
- last_error = cannot_close_error;
+ if (unload_add_on((image_id)module) != B_OK) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
}
static lt_ptr_t
-sys_bedl_sym (handle, symbol)
- lt_dlhandle handle;
+sys_bedl_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
const char *symbol;
{
lt_ptr_t address = 0;
- image_id image = (image_id)handle->handle;
+ image_id image = (image_id)module;
if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
&address) != B_OK) {
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
return address;
}
-static
-lt_dltype_t
-sys_bedl = { LTDL_TYPE_TOP, 0, sys_bedl_init, sys_bedl_exit,
- sys_bedl_open, sys_bedl_close, sys_bedl_sym };
+static struct lt_user_dlloader
+sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 };
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_bedl
+#endif
+
+#if HAVE_DLD
+
+/* dynamic linking with dld */
+
+#if HAVE_DLD_H
+#include <dld.h>
+#endif
+
+static lt_module_t
+sys_dld_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
+ const char *filename;
+{
+ lt_module_t module = strdup(filename);
+ if (!module) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 0;
+ }
+ if (dld_link(filename) != 0) {
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
+ lt_dlfree(module);
+ return 0;
+ }
+ return module;
+}
+
+static int
+sys_dld_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
+{
+ if (dld_unlink_by_file((char*)(module), 1) != 0) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
+ return 1;
+ }
+ lt_dlfree(module);
+ return 0;
+}
+
+static lt_ptr_t
+sys_dld_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
+ const char *symbol;
+{
+ lt_ptr_t address = dld_get_func(symbol);
+
+ if (!address)
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
+ return address;
+}
+
+static struct lt_user_dlloader
+sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 };
#endif
@@ -690,7 +667,8 @@ static const lt_dlsymlist *default_preloaded_symbols = 0;
static lt_dlsymlists_t *preloaded_symbols = 0;
static int
-presym_init LTDL_PARAMS((void))
+presym_init (loader_data)
+ lt_dlloader_data_t loader_data;
{
preloaded_symbols = 0;
if (default_preloaded_symbols)
@@ -714,7 +692,8 @@ presym_free_symlists LTDL_PARAMS((void))
}
static int
-presym_exit LTDL_PARAMS((void))
+presym_exit (loader_data)
+ lt_dlloader_data_t loader_data;
{
presym_free_symlists();
return 0;
@@ -735,33 +714,25 @@ presym_add_symlist (preloaded)
tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
tmp->syms = preloaded;
- tmp->next = 0;
- if (!preloaded_symbols)
- preloaded_symbols = tmp;
- else {
- /* append to the end */
- lists = preloaded_symbols;
- while (lists->next)
- lists = lists->next;
- lists->next = tmp;
- }
+ tmp->next = preloaded_symbols;
+ preloaded_symbols = tmp;
return 0;
}
-static int
-presym_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+presym_open (loader_data, filename)
+ lt_dlloader_data_t loader_data;
const char *filename;
{
lt_dlsymlists_t *lists = preloaded_symbols;
if (!lists) {
- last_error = no_symbols_error;
- return 1;
+ last_error = LT_DLSTRERROR(NO_SYMBOLS);
+ return 0;
}
if (!filename)
filename = "@PROGRAM@";
@@ -771,32 +742,33 @@ presym_open (handle, filename)
while (syms->name) {
if (!syms->address &&
strcmp(syms->name, filename) == 0) {
- handle->handle = (lt_ptr_t) syms;
- return 0;
+ return (lt_module_t) syms;
}
syms++;
}
lists = lists->next;
}
- last_error = file_not_found_error;
- return 1;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
+ return 0;
}
static int
-presym_close (handle)
- lt_dlhandle handle;
+presym_close (loader_data, module)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
{
/* Just to silence gcc -Wall */
- handle = 0;
+ module = 0;
return 0;
}
static lt_ptr_t
-presym_sym (handle, symbol)
- lt_dlhandle handle;
+presym_sym (loader_data, module, symbol)
+ lt_dlloader_data_t loader_data;
+ lt_module_t module;
const char *symbol;
{
- lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
+ lt_dlsymlist *syms = (lt_dlsymlist*)(module);
syms++;
while (syms->address) {
@@ -804,31 +776,24 @@ presym_sym (handle, symbol)
return syms->address;
syms++;
}
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
-static
-lt_dltype_t
-presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit,
- presym_open, presym_close, presym_sym };
+static struct lt_user_dlloader
+presym = { 0, presym_open, presym_close, presym_sym, presym_exit, 0 };
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &presym
static char *user_search_path = 0;
+static lt_dlloader_t *loaders = 0;
static lt_dlhandle handles = 0;
static int initialized = 0;
-static lt_dltype_t *types = LTDL_TYPE_TOP;
-#undef LTDL_TYPE_TOP
-
int
lt_dlinit LTDL_PARAMS((void))
{
/* initialize libltdl */
- lt_dltype_t **type = &types;
- int typecount = 0;
+ int errors = 0;
if (initialized) { /* Initialize only at first call. */
initialized++;
@@ -836,17 +801,30 @@ lt_dlinit LTDL_PARAMS((void))
}
handles = 0;
user_search_path = 0; /* empty search path */
-
- while (*type) {
- if ((*type)->mod_init())
- *type = (*type)->next; /* Remove it from the list */
- else {
- type = &(*type)->next; /* Keep it */
- typecount++;
- }
+
+#if HAVE_LIBDL && !defined(__CYGWIN__)
+ errors += lt_dlloader_add (lt_dlloader_next(0), &sys_dl, "dlopen");
+#endif
+#if HAVE_SHL_LOAD
+ errors += lt_dlloader_add (lt_dlloader_next(0), &sys_shl, "dlopen");
+#endif
+#ifdef _WIN32
+ errors += lt_dlloader_add (lt_dlloader_next(0), &sys_wll, "dlopen");
+#endif
+#ifdef __BEOS__
+ errors += lt_dlloader_add (lt_dlloader_next(0), &sys_bedl, "dlopen");
+#endif
+#if HAVE_DLD
+ errors += lt_dlloader_add (lt_dlloader_next(0), &sys_dld, "dld");
+#endif
+ errors += lt_dlloader_add (lt_dlloader_next(0), &presym, "dlpreload");
+ if (presym_init(presym.dlloader_data)) {
+ last_error = LT_DLSTRERROR(INIT_LOADER);
+ return 1;
}
- if (typecount == 0) {
- last_error = dlopen_not_supported_error;
+
+ if (errors != 0) {
+ last_error = LT_DLSTRERROR(DLOPEN_NOT_SUPPORTED);
return 1;
}
last_error = 0;
@@ -878,11 +856,11 @@ int
lt_dlexit LTDL_PARAMS((void))
{
/* shut down libltdl */
- lt_dltype_t *type = types;
- int errors;
+ lt_dlloader_t *loader = loaders;
+ int errors, level;
if (!initialized) {
- last_error = shutdown_error;
+ last_error = LT_DLSTRERROR(SHUTDOWN);
return 1;
}
if (initialized != 1) { /* shut down only at last call. */
@@ -891,17 +869,27 @@ lt_dlexit LTDL_PARAMS((void))
}
/* close all modules */
errors = 0;
- while (handles) {
- /* FIXME: what if a module depends on another one? */
- if (lt_dlclose(handles))
- errors++;
+ for (level = 1; handles; level++) {
+ lt_dlhandle cur = handles;
+ while (cur) {
+ lt_dlhandle tmp = cur;
+ cur = cur->next;
+ if (tmp->info.ref_count <= level)
+ if (lt_dlclose(tmp))
+ errors++;
+ }
}
- initialized = 0;
- while (type) {
- if (type->mod_exit())
+ /* close all loaders */
+ while (loader) {
+ lt_dlloader_t *next = loader->next;
+ lt_dlloader_data_t data = loader->dlloader_data;
+ if (loader->dlloader_exit && loader->dlloader_exit(data))
errors++;
- type = type->next;
+ lt_dlfree (loader);
+ loader = next;
}
+
+ initialized = 0;
return errors;
}
@@ -910,46 +898,49 @@ tryall_dlopen (handle, filename)
lt_dlhandle *handle;
const char *filename;
{
- lt_dlhandle cur;
- lt_dltype_t *type = types;
+ lt_dlhandle cur = handles;
+ lt_dlloader_t *loader = loaders;
const char *saved_error = last_error;
/* check whether the module was already opened */
- cur = handles;
while (cur) {
- if (!cur->filename && !filename)
+ /* try to dlopen the program itself? */
+ if (!cur->info.filename && !filename)
break;
- if (cur->filename && filename &&
- strcmp(cur->filename, filename) == 0)
+ if (cur->info.filename && filename &&
+ strcmp(cur->info.filename, filename) == 0)
break;
cur = cur->next;
}
+
if (cur) {
- cur->usage++;
+ cur->info.ref_count++;
*handle = cur;
return 0;
}
cur = *handle;
if (filename) {
- cur->filename = strdup(filename);
- if (!cur->filename) {
- last_error = memory_error;
+ cur->info.filename = strdup(filename);
+ if (!cur->info.filename) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
} else
- cur->filename = 0;
- while (type) {
- if (type->lib_open(cur, filename) == 0)
+ cur->info.filename = 0;
+ while (loader) {
+ lt_dlloader_data_t data = loader->dlloader_data;
+ cur->module = loader->module_open(data, filename);
+ if (cur->module != 0)
break;
- type = type->next;
+ loader = loader->next;
}
- if (!type) {
- if (cur->filename)
- lt_dlfree(cur->filename);
+ if (!loader) {
+ if (cur->info.filename)
+ lt_dlfree(cur->info.filename);
return 1;
}
- cur->type = type;
+ cur->loader = loader;
last_error = saved_error;
return 0;
}
@@ -977,15 +968,13 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
filename = (char*)
lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
if (!filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
- strcpy(filename, libdir);
- strcat(filename, "/");
- strcat(filename, dlname);
- error = tryall_dlopen(handle, filename) == 0;
+ sprintf (filename, "%s/%s", libdir, dlname);
+ error = tryall_dlopen(handle, filename) != 0;
lt_dlfree(filename);
- if (error)
+ if (!error)
return 0;
}
/* try to open the not-installed module */
@@ -994,7 +983,7 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
lt_dlmalloc((dir ? strlen(dir) : 0)
+ strlen(objdir) + strlen(dlname) + 1);
if (!filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
if (dir)
@@ -1004,12 +993,12 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
strcat(filename, objdir);
strcat(filename, dlname);
- error = tryall_dlopen(handle, filename) == 0;
+ error = tryall_dlopen(handle, filename) != 0;
lt_dlfree(filename);
- if (error)
+ if (!error)
return 0;
}
- /* hmm, maybe it was moved to another directory */
+ /* maybe it was moved to another directory */
{
filename = (char*)
lt_dlmalloc((dir ? strlen(dir) : 0)
@@ -1019,16 +1008,34 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
else
*filename = 0;
strcat(filename, dlname);
- error = tryall_dlopen(handle, filename) == 0;
+ error = tryall_dlopen(handle, filename) != 0;
lt_dlfree(filename);
- if (error)
+ if (!error)
return 0;
}
}
- last_error = file_not_found_error;
return 1;
}
+static char*
+canonicalize_path (path)
+ const char *path;
+{
+ char *canonical = 0;
+
+ if (path && *path) {
+ char *ptr = strdup (path);
+ canonical = ptr;
+#ifdef LTDL_DIRSEP_CHAR
+ /* Avoid this overhead where '/' is the only separator. */
+ while (ptr = strchr (ptr, LTDL_DIRSEP_CHAR))
+ *ptr++ = '/';
+#endif
+ }
+
+ return canonical;
+}
+
static lt_ptr_t
find_file (basename, search_path, pdir, handle)
const char *basename;
@@ -1039,24 +1046,31 @@ find_file (basename, search_path, pdir, handle)
/* when handle != NULL search a library, otherwise a file */
/* return NULL on failure, otherwise the file/handle */
+ lt_ptr_t result = 0;
char *filename = 0;
int filenamesize = 0;
- const char *next = search_path;
int lenbase = strlen(basename);
+ char *canonical = 0, *next = 0;
- if (!next || !*next) {
- last_error = file_not_found_error;
+ if (!search_path || !*search_path) {
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
return 0;
}
+ canonical = canonicalize_path (search_path);
+ if (!canonical) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ goto cleanup;
+ }
+ next = canonical;
while (next) {
int lendir;
- const char *cur = next;
+ char *cur = next;
- next = strchr(cur, ':');
+ next = strchr(cur, LTDL_PATHSEP_CHAR);
if (!next)
next = cur + strlen(cur);
lendir = next - cur;
- if (*next == ':')
+ if (*next == LTDL_PATHSEP_CHAR)
++next;
else
next = 0;
@@ -1068,8 +1082,8 @@ find_file (basename, search_path, pdir, handle)
filenamesize = lendir + 1 + lenbase + 1;
filename = (char*) lt_dlmalloc(filenamesize);
if (!filename) {
- last_error = memory_error;
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ goto cleanup;
}
}
strncpy(filename, cur, lendir);
@@ -1078,8 +1092,8 @@ find_file (basename, search_path, pdir, handle)
strcpy(filename+lendir, basename);
if (handle) {
if (tryall_dlopen(handle, filename) == 0) {
- lt_dlfree(filename);
- return (lt_ptr_t) handle;
+ result = (lt_ptr_t) handle;
+ goto cleanup;
}
} else {
FILE *file = fopen(filename, LTDL_READTEXT_MODE);
@@ -1093,39 +1107,142 @@ find_file (basename, search_path, pdir, handle)
strdup, but there would be some
memory overhead. */
*pdir = filename;
- } else
- lt_dlfree(filename);
- return (lt_ptr_t) file;
+ filename = 0;
+ }
+ result = (lt_ptr_t) file;
+ goto cleanup;
}
}
}
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
+cleanup:
if (filename)
lt_dlfree(filename);
- last_error = file_not_found_error;
- return 0;
+ if (canonical)
+ lt_dlfree(canonical);
+ return result;
}
static int
load_deplibs(handle, deplibs)
lt_dlhandle handle;
- const char *deplibs;
+ char *deplibs;
{
- /* FIXME: load deplibs */
+ char *p, *save_search_path;
+ int i;
+ int ret = 1, depcount = 0;
+ char **names = 0;
+ lt_dlhandle *handles = 0;
+
handle->depcount = 0;
- handle->deplibs = 0;
- /* Just to silence gcc -Wall */
- deplibs = 0;
- return 0;
+ if (!deplibs)
+ return 0;
+ save_search_path = strdup(user_search_path);
+ if (user_search_path && !save_search_path) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 1;
+ }
+ p = deplibs;
+ /* extract search paths and count deplibs */
+ while (*p) {
+ if (!isspace(*p)) {
+ char *end = p+1;
+ while (*end && !isspace(*end)) end++;
+ if (strncmp(p, "-L", 2) == 0 ||
+ strncmp(p, "-R", 2) == 0) {
+ char save = *end;
+ *end = 0; /* set a temporary string terminator */
+ if (lt_dladdsearchdir(p+2))
+ goto cleanup;
+ *end = save;
+ } else
+ depcount++;
+ p = end;
+ } else
+ p++;
+ }
+ if (!depcount) {
+ ret = 0;
+ goto cleanup;
+ }
+ names = (char**)lt_dlmalloc(depcount * sizeof(char*));
+ if (!names)
+ goto cleanup;
+ handles = (lt_dlhandle*)lt_dlmalloc(depcount * sizeof(lt_dlhandle*));
+ if (!handles)
+ goto cleanup;
+ depcount = 0;
+ /* now only extract the actual deplibs */
+ p = deplibs;
+ while (*p) {
+ if (!isspace(*p)) {
+ char *end = p+1;
+ while (*end && !isspace(*end)) end++;
+ if (strncmp(p, "-L", 2) != 0 &&
+ strncmp(p, "-R", 2) != 0) {
+ char *name;
+ char save = *end;
+ *end = 0; /* set a temporary string terminator */
+ if (strncmp(p, "-l", 2) == 0) {
+ name = lt_dlmalloc(3+ /* "lib" */
+ strlen(p+2)+1);
+ if (name)
+ sprintf (name, "lib%s", p+2);
+ } else
+ name = strdup(p);
+ if (name)
+ names[depcount++] = name;
+ else
+ goto cleanup_names;
+ *end = save;
+ }
+ p = end;
+ } else
+ p++;
+ }
+ /* load the deplibs (in reverse order) */
+ for (i = 0; i < depcount; i++) {
+ lt_dlhandle handle = lt_dlopenext(names[depcount-1-i]);
+ if (!handle) {
+ int j;
+ for (j = 0; j < i; j++)
+ lt_dlclose(handles[j]);
+ last_error = LT_DLSTRERROR(DEPLIB_NOT_FOUND);
+ goto cleanup_names;
+ }
+ handles[i] = handle;
+ }
+ handle->depcount = depcount;
+ handle->deplibs = handles;
+ handles = 0;
+ ret = 0;
+cleanup_names:
+ for (i = 0; i < depcount; i++)
+ lt_dlfree(names[i]);
+cleanup:
+ if (names)
+ lt_dlfree(names);
+ if (handles)
+ lt_dlfree(handles);
+ /* restore the old search path */
+ if (user_search_path)
+ lt_dlfree(user_search_path);
+ user_search_path = save_search_path;
+ return ret;
}
static int
unload_deplibs(handle)
lt_dlhandle handle;
{
- /* FIXME: unload deplibs */
- /* Just to silence gcc -Wall */
- handle = 0;
- return 0;
+ int i;
+ int errors = 0;
+
+ if (!handle->depcount)
+ return 0;
+ for (i = 0; i < handle->depcount; i++)
+ errors += lt_dlclose(handle->deplibs[i]);
+ return errors;
}
static inline int
@@ -1144,7 +1261,7 @@ trim (dest, str)
if (len > 3 && str[0] == '\'') {
tmp = (char*) lt_dlmalloc(end - str);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
strncpy(tmp, &str[1], (end - str) - 1);
@@ -1156,18 +1273,12 @@ trim (dest, str)
}
static inline int
-free_vars(dir, name, dlname, oldname, libdir, deplibs)
- char *dir;
- char *name;
+free_vars( dlname, oldname, libdir, deplibs)
char *dlname;
char *oldname;
char *libdir;
char *deplibs;
{
- if (dir)
- lt_dlfree(dir);
- if (name)
- lt_dlfree(name);
if (dlname)
lt_dlfree(dlname);
if (oldname)
@@ -1183,18 +1294,18 @@ lt_dlhandle
lt_dlopen (filename)
const char *filename;
{
- lt_dlhandle handle, newhandle;
- const char *basename, *ext;
+ lt_dlhandle handle = 0, newhandle;
+ const char *ext;
const char *saved_error = last_error;
- char *dir = 0, *name = 0;
+ char *canonical = 0, *basename = 0, *dir = 0, *name = 0;
if (!filename) {
handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
if (!handle) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
- handle->usage = 0;
+ handle->info.ref_count = 0;
handle->depcount = 0;
handle->deplibs = 0;
newhandle = handle;
@@ -1204,18 +1315,26 @@ lt_dlopen (filename)
}
goto register_handle;
}
- basename = strrchr(filename, '/');
+ canonical = canonicalize_path (filename);
+ if (!canonical) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ if (handle)
+ lt_dlfree(handle);
+ return 0;
+ }
+ basename = strrchr(canonical, '/');
if (basename) {
basename++;
- dir = (char*) lt_dlmalloc(basename - filename + 1);
+ dir = (char*) lt_dlmalloc(basename - canonical + 1);
if (!dir) {
- last_error = memory_error;
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ handle = 0;
+ goto cleanup;
}
- strncpy(dir, filename, basename - filename);
- dir[basename - filename] = '\0';
+ strncpy(dir, canonical, basename - canonical);
+ dir[basename - canonical] = '\0';
} else
- basename = filename;
+ basename = canonical;
/* check whether we open a libtool module (.la extension) */
ext = strrchr(basename, '.');
if (ext && strcmp(ext, ".la") == 0) {
@@ -1234,10 +1353,9 @@ lt_dlopen (filename)
/* extract the module name from the file name */
name = (char*) lt_dlmalloc(ext - basename + 1);
if (!name) {
- last_error = memory_error;
- if (dir)
- lt_dlfree(dir);
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ handle = 0;
+ goto cleanup;
}
/* canonicalize the module name */
for (i = 0; i < ext - basename; i++)
@@ -1249,7 +1367,7 @@ lt_dlopen (filename)
/* now try to open the .la file */
file = fopen(filename, LTDL_READTEXT_MODE);
if (!file)
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
if (!file && !dir) {
/* try other directories */
file = (FILE*) find_file(basename,
@@ -1265,19 +1383,23 @@ lt_dlopen (filename)
getenv(LTDL_SHLIBPATH_VAR),
&dir, 0);
#endif
+#ifdef LTDL_SYSSEARCHPATH
+ if (!file)
+ file = (FILE*) find_file(basename,
+ sys_search_path,
+ &dir, 0);
+#endif
}
if (!file) {
- if (name)
- lt_dlfree(name);
- if (dir)
- lt_dlfree(dir);
- return 0;
+ handle = 0;
+ goto cleanup;
}
line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
if (!line) {
fclose(file);
- last_error = memory_error;
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ handle = 0;
+ goto cleanup;
}
/* read the .la file */
while (!feof(file)) {
@@ -1318,6 +1440,22 @@ lt_dlopen (filename)
else
if (strcmp(line, "installed=no\n") == 0)
installed = 0;
+ else
+# undef STR_LIBRARY_NAMES
+# define STR_LIBRARY_NAMES "library_names="
+ if (! dlname &&
+ strncmp(line, STR_LIBRARY_NAMES,
+ sizeof(STR_LIBRARY_NAMES) - 1) == 0) {
+ char *last_libname;
+ error = trim(&dlname,
+ &line[sizeof(STR_LIBRARY_NAMES) - 1]);
+ if (! error && dlname &&
+ (last_libname = strrchr(dlname, ' ')) != NULL) {
+ last_libname = strdup(last_libname + 1);
+ free(dlname);
+ dlname = last_libname;
+ }
+ }
if (error)
break;
}
@@ -1329,11 +1467,12 @@ lt_dlopen (filename)
if (handle)
lt_dlfree(handle);
if (!error)
- last_error = memory_error;
- free_vars(name, dir, dlname, old_name, libdir, deplibs);
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ free_vars(dlname, old_name, libdir, deplibs);
+ /* handle is already set to 0 */
+ goto cleanup;
}
- handle->usage = 0;
+ handle->info.ref_count = 0;
if (load_deplibs(handle, deplibs) == 0) {
newhandle = handle;
/* find_module may replace newhandle */
@@ -1344,24 +1483,23 @@ lt_dlopen (filename)
}
} else
error = 1;
+ free_vars(dlname, old_name, libdir, deplibs);
if (error) {
lt_dlfree(handle);
- free_vars(name, dir, dlname, old_name, libdir, deplibs);
- return 0;
+ handle = 0;
+ goto cleanup;
}
- if (handle != newhandle) {
+ if (handle != newhandle)
unload_deplibs(handle);
- }
} else {
/* not a libtool module */
handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
if (!handle) {
- last_error = memory_error;
- if (dir)
- lt_dlfree(dir);
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ /* handle is already set to 0 */
+ goto cleanup;
}
- handle->usage = 0;
+ handle->info.ref_count = 0;
/* non-libtool modules don't have dependencies */
handle->depcount = 0;
handle->deplibs = 0;
@@ -1378,11 +1516,14 @@ lt_dlopen (filename)
getenv(LTDL_SHLIBPATH_VAR),
0, &newhandle)
#endif
+#ifdef LTDL_SYSSEARCHPATH
+ && !find_file(basename, sys_search_path,
+ 0, &newhandle)
+#endif
))) {
lt_dlfree(handle);
- if (dir)
- lt_dlfree(dir);
- return 0;
+ handle = 0;
+ goto cleanup;
}
}
register_handle:
@@ -1390,16 +1531,21 @@ register_handle:
lt_dlfree(handle);
handle = newhandle;
}
- if (!handle->usage) {
- handle->usage = 1;
- handle->name = name;
+ if (!handle->info.ref_count) {
+ handle->info.ref_count = 1;
+ handle->info.name = name;
handle->next = handles;
handles = handle;
- } else if (name)
- lt_dlfree(name);
+ name = 0; /* don't free this during `cleanup' */
+ }
+ last_error = saved_error;
+cleanup:
if (dir)
lt_dlfree(dir);
- last_error = saved_error;
+ if (name)
+ lt_dlfree(name);
+ if (canonical)
+ lt_dlfree(canonical);
return handle;
}
@@ -1416,7 +1562,7 @@ lt_dlopenext (filename)
return lt_dlopen(filename);
len = strlen(filename);
if (!len) {
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
return 0;
}
/* try the normal file name */
@@ -1426,7 +1572,7 @@ lt_dlopenext (filename)
/* try "filename.la" */
tmp = (char*) lt_dlmalloc(len+4);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
strcpy(tmp, filename);
@@ -1443,7 +1589,7 @@ lt_dlopenext (filename)
lt_dlfree(tmp);
tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
strcpy(tmp, filename);
@@ -1457,7 +1603,7 @@ lt_dlopenext (filename)
return handle;
}
#endif
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
lt_dlfree(tmp);
return 0;
}
@@ -1475,23 +1621,24 @@ lt_dlclose (handle)
cur = cur->next;
}
if (!cur) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 1;
}
- handle->usage--;
- if (!handle->usage) {
+ handle->info.ref_count--;
+ if (!handle->info.ref_count) {
int error;
+ lt_dlloader_data_t data = handle->loader->dlloader_data;
if (handle != handles)
last->next = handle->next;
else
handles = handle->next;
- error = handle->type->lib_close(handle);
+ error = handle->loader->module_close(data, handle->module);
error += unload_deplibs(handle);
- if (handle->filename)
- lt_dlfree(handle->filename);
- if (handle->name)
- lt_dlfree(handle->name);
+ if (handle->info.filename)
+ lt_dlfree(handle->info.filename);
+ if (handle->info.name)
+ lt_dlfree(handle->info.name);
lt_dlfree(handle);
return error;
}
@@ -1507,41 +1654,43 @@ lt_dlsym (handle, symbol)
char lsym[LTDL_SYMBOL_LENGTH];
char *sym;
lt_ptr_t address;
+ lt_dlloader_data_t data;
if (!handle) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 0;
}
if (!symbol) {
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
lensym = strlen(symbol);
- if (handle->type->sym_prefix)
- lensym += strlen(handle->type->sym_prefix);
- if (handle->name)
- lensym += strlen(handle->name);
+ if (handle->loader->sym_prefix)
+ lensym += strlen(handle->loader->sym_prefix);
+ if (handle->info.name)
+ lensym += strlen(handle->info.name);
if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
sym = lsym;
else
sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
if (!sym) {
- last_error = buffer_overflow_error;
+ last_error = LT_DLSTRERROR(BUFFER_OVERFLOW);
return 0;
}
- if (handle->name) {
+ data = handle->loader->dlloader_data;
+ if (handle->info.name) {
const char *saved_error = last_error;
/* this is a libtool module */
- if (handle->type->sym_prefix) {
- strcpy(sym, handle->type->sym_prefix);
- strcat(sym, handle->name);
+ if (handle->loader->sym_prefix) {
+ strcpy(sym, handle->loader->sym_prefix);
+ strcat(sym, handle->info.name);
} else
- strcpy(sym, handle->name);
+ strcpy(sym, handle->info.name);
strcat(sym, "_LTX_");
strcat(sym, symbol);
/* try "modulename_LTX_symbol" */
- address = handle->type->find_sym(handle, sym);
+ address = handle->loader->find_sym(data, handle->module, sym);
if (address) {
if (sym != lsym)
lt_dlfree(sym);
@@ -1550,12 +1699,12 @@ lt_dlsym (handle, symbol)
last_error = saved_error;
}
/* otherwise try "symbol" */
- if (handle->type->sym_prefix) {
- strcpy(sym, handle->type->sym_prefix);
+ if (handle->loader->sym_prefix) {
+ strcpy(sym, handle->loader->sym_prefix);
strcat(sym, symbol);
} else
strcpy(sym, symbol);
- address = handle->type->find_sym(handle, sym);
+ address = handle->loader->find_sym(data, handle->module, sym);
if (sym != lsym)
lt_dlfree(sym);
return address;
@@ -1579,7 +1728,7 @@ lt_dladdsearchdir (search_dir)
if (!user_search_path) {
user_search_path = strdup(search_dir);
if (!user_search_path) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
} else {
@@ -1587,12 +1736,11 @@ lt_dladdsearchdir (search_dir)
lt_dlmalloc(strlen(user_search_path) +
strlen(search_dir) + 2); /* ':' + '\0' == 2 */
if (!new_search_path) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
- strcpy(new_search_path, user_search_path);
- strcat(new_search_path, ":");
- strcat(new_search_path, search_dir);
+ sprintf (new_search_path, "%s%c%s", user_search_path,
+ LTDL_PATHSEP_CHAR, search_dir);
lt_dlfree(user_search_path);
user_search_path = new_search_path;
}
@@ -1619,3 +1767,214 @@ lt_dlgetsearchpath LTDL_PARAMS((void))
{
return user_search_path;
}
+
+const lt_dlinfo *
+lt_dlgetinfo (handle)
+ lt_dlhandle handle;
+{
+ if (!handle) {
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
+ return 0;
+ }
+ return &(handle->info);
+}
+
+int
+lt_dlforeach (func, data)
+ int (*func) LTDL_PARAMS((lt_dlhandle handle, lt_ptr_t data));
+ lt_ptr_t data;
+{
+ lt_dlhandle cur = handles;
+ while (cur) {
+ lt_dlhandle tmp = cur;
+ cur = cur->next;
+ if (func(tmp, data))
+ return 1;
+ }
+ return 0;
+}
+
+int
+lt_dlloader_add (place, dlloader, loader_name)
+ lt_dlloader_t *place;
+ const struct lt_user_dlloader *dlloader;
+ const char *loader_name;
+{
+ lt_dlloader_t *node = 0, *ptr = 0;
+
+ if ((dlloader == 0) /* diagnose null parameters */
+ || (dlloader->module_open == 0)
+ || (dlloader->module_close == 0)
+ || (dlloader->find_sym == 0)) {
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return 1;
+ }
+
+ /* Create a new dlloader node with copies of the user callbacks. */
+ node = (lt_dlloader_t *) lt_dlmalloc (sizeof (lt_dlloader_t));
+ if (node == 0) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 1;
+ }
+ node->next = 0;
+ node->loader_name = loader_name;
+ node->sym_prefix = dlloader->sym_prefix;
+ node->dlloader_exit = dlloader->dlloader_exit;
+ node->module_open = dlloader->module_open;
+ node->module_close = dlloader->module_close;
+ node->find_sym = dlloader->find_sym;
+ node->dlloader_data = dlloader->dlloader_data;
+
+ if (!loaders)
+ /* If there are no loaders, NODE becomes the list! */
+ loaders = node;
+ else if (!place) {
+ /* If PLACE is not set, add NODE to the end of the
+ LOADERS list. */
+ for (ptr = loaders; ptr->next; ptr = ptr->next)
+ /*NOWORK*/;
+ ptr->next = node;
+ } else if (loaders == place) {
+ /* If PLACE is the first loader, NODE goes first. */
+ node->next = place;
+ loaders = node;
+ } else {
+ /* Find the node immediately preceding PLACE. */
+ for (ptr = loaders; ptr->next != place; ptr = ptr->next)
+ /*NOWORK*/;
+
+ if (ptr->next != place) {
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return 1;
+ }
+
+ /* Insert NODE between PTR and PLACE. */
+ node->next = place;
+ ptr->next = node;
+ }
+
+ return 0;
+}
+
+int
+lt_dlloader_remove (loader_name)
+ const char *loader_name;
+{
+ lt_dlloader_t *place = lt_dlloader_find (loader_name);
+ lt_dlhandle handle;
+ int result = 0;
+
+ if (!place) {
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return 1;
+ }
+
+ /* Fail if there are any open modules which use this loader. */
+ for (handle = handles; handle; handle = handle->next)
+ if (handle->loader == place) {
+ last_error = LT_DLSTRERROR(REMOVE_LOADER);
+ return 1;
+ }
+
+ if (place == loaders)
+ /* PLACE is the first loader in the list. */
+ loaders = loaders->next;
+ else {
+ /* Find the loader before the one being removed. */
+ lt_dlloader_t *prev;
+ for (prev = loaders; prev->next; prev = prev->next)
+ if (!strcmp (prev->next->loader_name, loader_name))
+ break;
+
+ place = prev->next;
+ prev->next = prev->next->next;
+ }
+ if (place->dlloader_exit)
+ result = place->dlloader_exit (place->dlloader_data);
+ lt_dlfree (place);
+
+ return result;
+}
+
+lt_dlloader_t *
+lt_dlloader_next (place)
+ lt_dlloader_t *place;
+{
+ return place ? place->next : loaders;
+}
+
+const char *
+lt_dlloader_name (place)
+ lt_dlloader_t *place;
+{
+ if (!place)
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return place ? place->loader_name : 0;
+}
+
+lt_dlloader_data_t *
+lt_dlloader_data (place)
+ lt_dlloader_t *place;
+{
+ if (!place)
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return place ? &(place->dlloader_data) : 0;
+}
+
+lt_dlloader_t *
+lt_dlloader_find (loader_name)
+ const char *loader_name;
+{
+ lt_dlloader_t *place = 0;
+
+ for (place = loaders; place; place = place->next)
+ if (strcmp (place->loader_name, loader_name) == 0)
+ break;
+
+ return place;
+}
+
+static const char **user_error_strings = 0;
+static int errorcode = LTDL_ERROR_MAX;
+
+int
+lt_dladderror (diagnostic)
+ const char *diagnostic;
+{
+ int index = errorcode - LTDL_ERROR_MAX;
+ const char **temp = 0;
+
+ /* realloc is not entirely portable, so simulate it using
+ lt_dlmalloc and lt_dlfree. */
+ temp = (const char **) lt_dlmalloc ((1+index) * sizeof(const char*));
+ if (temp == 0) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return -1;
+ }
+
+ /* Build the new vector in the memory addressed by temp. */
+ temp[index] = diagnostic;
+ while (--index >= 0)
+ temp[index] = user_error_strings[index];
+
+ lt_dlfree (user_error_strings);
+ user_error_strings = temp;
+ return errorcode++;
+}
+
+int
+lt_dlseterror (index)
+ int index;
+{
+ if (index >= errorcode || index < 0) {
+ last_error = LT_DLSTRERROR(INVALID_ERRORCODE);
+ return 1;
+ }
+
+ if (index < LTDL_ERROR_MAX)
+ last_error = ltdl_error_strings[errorcode];
+ else
+ last_error = user_error_strings[errorcode - LTDL_ERROR_MAX];
+
+ return 0;
+}
diff --git a/libjava/libltdl/ltdl.h b/libjava/libltdl/ltdl.h
index c0e446b87ef..666c785c8c1 100644
--- a/libjava/libltdl/ltdl.h
+++ b/libjava/libltdl/ltdl.h
@@ -1,24 +1,24 @@
/* ltdl.h -- generic dlopen functions
- Copyright (C) 1998-1999 Free Software Foundation, Inc.
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
Originally by Thomas Tanner <tanner@ffii.org>
This file is part of GNU Libtool.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
+modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
-As a special exception to the GNU Library General Public License,
-if you distribute this file as part of a program that uses GNU libtool
-to create libraries and programs, you may include it under the same
+As a special exception to the GNU Lesser General Public License,
+if you distribute this file as part of a program or library that
+is built using GNU libtool, you may include it under the same
distribution terms that you use for the rest of that program.
This library 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
-Library General Public License for more details.
+Lesser General Public License for more details.
-You should have received a copy of the GNU Library General Public
+You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
@@ -28,6 +28,18 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
#ifndef _LTDL_H_
#define _LTDL_H_ 1
+/* Canonicalise Windows and Cygwin recognition macros. */
+#ifdef __CYGWIN32__
+# ifndef __CYGWIN__
+# define __CYGWIN__ __CYGWIN32__
+# endif
+#endif
+#ifdef _WIN32
+# ifndef WIN32
+# define WIN32 _WIN32
+# endif
+#endif
+
/* __BEGIN_DECLS should be used at the beginning of your declarations,
so that C++ compilers don't mangle their names. Use __END_DECLS at
the end of C declarations. */
@@ -54,38 +66,184 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# define lt_ptr_t char*
#endif
+/* LTDL_STMT_START/END are used to create macros which expand to a
+ a single compound statement in a portable way. */
+#undef LTDL_STMT_START
+#undef LTDL_STMT_END
+#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
+# define LTDL_STMT_START (void)(
+# define LTDL_STMT_END )
+#else
+# if (defined (sun) || defined (__sun__))
+# define LTDL_STMT_START if (1)
+# define LTDL_STMT_END else (void)0
+# else
+# define LTDL_STMT_START do
+# define LTDL_STMT_END while (0)
+# endif
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__
+/* LTDL_DIRSEP_CHAR is accepted *in addition* to '/' as a directory
+ separator when it is set. */
+# define LTDL_DIRSEP_CHAR '\\'
+# define LTDL_PATHSEP_CHAR ';'
+# endif
+#endif
+#ifndef LTDL_PATHSEP_CHAR
+# define LTDL_PATHSEP_CHAR ':'
+#endif
+
+/* DLL building support on win32 hosts; mostly to workaround their
+ ridiculous implementation of data symbol exporting. */
+#ifndef LTDL_SCOPE
+# ifdef _WIN32
+# ifdef DLL_EXPORT /* defined by libtool (if required) */
+# define LTDL_SCOPE __declspec(dllexport)
+# endif
+# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */
+# define LTDL_SCOPE extern __declspec(dllimport)
+# endif
+# endif
+# ifndef LTDL_SCOPE /* static linking or !_WIN32 */
+# define LTDL_SCOPE extern
+# endif
+#endif
+
#include <stdlib.h>
+/* Defining error strings alongside their symbolic names in a macro in
+ this way allows us to expand the macro in different contexts with
+ confidence that the enumeration of symbolic names will map correctly
+ onto the table of error strings. */
+#define ltdl_error_table \
+ LTDL_ERROR(UNKNOWN, "unknown error") \
+ LTDL_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available")\
+ LTDL_ERROR(INVALID_LOADER, "invalid loader") \
+ LTDL_ERROR(INIT_LOADER, "loader initialization failed") \
+ LTDL_ERROR(REMOVE_LOADER, "loader removal failed") \
+ LTDL_ERROR(FILE_NOT_FOUND, "file not found") \
+ LTDL_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \
+ LTDL_ERROR(NO_SYMBOLS, "no symbols defined") \
+ LTDL_ERROR(CANNOT_OPEN, "can't open the module") \
+ LTDL_ERROR(CANNOT_CLOSE, "can't close the module") \
+ LTDL_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \
+ LTDL_ERROR(NO_MEMORY, "not enough memory") \
+ LTDL_ERROR(INVALID_HANDLE, "invalid module handle") \
+ LTDL_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \
+ LTDL_ERROR(INVALID_ERRORCODE, "invalid errorcode") \
+ LTDL_ERROR(SHUTDOWN, "library already shutdown")
+
+/* Enumerate the symbolic error names. */
+#if defined(__STDC__) || defined(__cplusplus)
+# define LTDL_ERROR(name, diagnostic) LTDL_ERROR_##name,
+#else
+# define LTDL_ERROR(name, diagnostic) LTDL_ERROR_/**/name,
+#endif
+enum {
+ ltdl_error_table
+ LTDL_ERROR_MAX
+};
+#undef LTDL_ERROR
+
+/* An opaque handle for a successfully lt_dlopened module instance. */
#ifdef _LTDL_COMPILE_
typedef struct lt_dlhandle_t *lt_dlhandle;
#else
typedef lt_ptr_t lt_dlhandle;
#endif
+/* A preopened symbol. Arrays of this type comprise the exported
+ symbols for a dlpreopened module. */
typedef struct {
const char *name;
lt_ptr_t address;
} lt_dlsymlist;
+/* Read only information pertaining to a loaded module. */
+typedef struct {
+ char *filename; /* file name */
+ char *name; /* module name */
+ int ref_count; /* number of times lt_dlopened minus
+ number of times lt_dlclosed. */
+} lt_dlinfo;
+
+/* An opaque handle for a module loaded by a system call. This is only
+ used internally by ltdl loaders, and by user module loaders. */
+typedef lt_ptr_t lt_module_t;
+
+/* An opaque handle for a module loader. */
+#ifdef _LTDL_COMPILE_
+typedef struct lt_dlloader_t lt_dlloader_t;
+#else
+typedef lt_ptr_t lt_dlloader_t;
+#endif
+
+typedef lt_ptr_t lt_dlloader_data_t;
+
+/* Function pointer types for creating user defined module loaders. */
+typedef lt_module_t lt_module_open_t LTDL_PARAMS((lt_dlloader_data_t loader_data, const char *filename));
+typedef int lt_module_close_t LTDL_PARAMS((lt_dlloader_data_t loader_data, lt_module_t handle));
+typedef lt_ptr_t lt_find_sym_t LTDL_PARAMS((lt_dlloader_data_t loader_data, lt_module_t handle, const char *symbol));
+typedef int lt_dlloader_exit_t LTDL_PARAMS((lt_dlloader_data_t loader_data));
+
__BEGIN_DECLS
+/* Initialisation and finalisation functions for libltdl. */
extern int lt_dlinit LTDL_PARAMS((void));
-extern int lt_dlpreload LTDL_PARAMS((const lt_dlsymlist *preloaded));
-extern int lt_dlpreload_default LTDL_PARAMS((const lt_dlsymlist *preloaded));
extern int lt_dlexit LTDL_PARAMS((void));
+
+/* Module search path manipultation. */
+extern int lt_dladdsearchdir LTDL_PARAMS((const char *search_dir));
+extern int lt_dlsetsearchpath LTDL_PARAMS((const char *search_path));
+extern const char *lt_dlgetsearchpath LTDL_PARAMS((void));
+
+/* Portable libltdl versions of the system dlopen() API. */
extern lt_dlhandle lt_dlopen LTDL_PARAMS((const char *filename));
extern lt_dlhandle lt_dlopenext LTDL_PARAMS((const char *filename));
-extern int lt_dlclose LTDL_PARAMS((lt_dlhandle handle));
extern lt_ptr_t lt_dlsym LTDL_PARAMS((lt_dlhandle handle, const char *name));
extern const char *lt_dlerror LTDL_PARAMS((void));
-extern int lt_dladdsearchdir LTDL_PARAMS((const char *search_dir));
-extern int lt_dlsetsearchpath LTDL_PARAMS((const char *search_path));
-extern const char *lt_dlgetsearchpath LTDL_PARAMS((void));
+extern int lt_dlclose LTDL_PARAMS((lt_dlhandle handle));
+
+/* Support for preloaded modules through lt_dlopen() API. */
+extern int lt_dlpreload LTDL_PARAMS((const lt_dlsymlist *preloaded));
+extern int lt_dlpreload_default LTDL_PARAMS((const lt_dlsymlist *preloaded));
+
+#define LTDL_SET_PRELOADED_SYMBOLS() LTDL_STMT_START{ \
+ extern const lt_dlsymlist lt_preloaded_symbols[]; \
+ lt_dlpreload_default(lt_preloaded_symbols); \
+ }LTDL_STMT_END
+
+/* Managing user data associated with a loaded modules. */
+extern const lt_dlinfo *lt_dlgetinfo LTDL_PARAMS((lt_dlhandle handle));
+extern int lt_dlforeach LTDL_PARAMS((
+ int (*func)(lt_dlhandle handle, lt_ptr_t data), lt_ptr_t data));
+
+/* User module loader API. */
+struct lt_user_dlloader {
+ const char *sym_prefix;
+ lt_module_open_t *module_open;
+ lt_module_close_t *module_close;
+ lt_find_sym_t *find_sym;
+ lt_dlloader_exit_t *dlloader_exit;
+ lt_dlloader_data_t dlloader_data;
+};
+
+extern lt_dlloader_t *lt_dlloader_next LTDL_PARAMS((lt_dlloader_t *place));
+extern lt_dlloader_t *lt_dlloader_find LTDL_PARAMS((const char *loader_name));
+extern const char *lt_dlloader_name LTDL_PARAMS((lt_dlloader_t *place));
+extern lt_dlloader_data_t *lt_dlloader_data LTDL_PARAMS((lt_dlloader_t *place));
+extern lt_dlloader_t *lt_find_dlloader LTDL_PARAMS((const char *loader_name));
+extern int lt_dlloader_add LTDL_PARAMS((lt_dlloader_t *place, const struct lt_user_dlloader *dlloader, const char *loader_name));
+extern int lt_dlloader_remove LTDL_PARAMS((const char *loader_name));
-extern const lt_dlsymlist lt_preloaded_symbols[];
-#define LTDL_SET_PRELOADED_SYMBOLS() lt_dlpreload_default(lt_preloaded_symbols)
+/* Integrated lt_dlerror() messages for user loaders. */
+extern int lt_dladderror LTDL_PARAMS((const char *diagnostic));
+extern int lt_dlseterror LTDL_PARAMS((int errorcode));
-extern lt_ptr_t (*lt_dlmalloc)LTDL_PARAMS((size_t size));
-extern void (*lt_dlfree)LTDL_PARAMS((lt_ptr_t ptr));
+/* Pointers to memory management functions to be used by libltdl. */
+LTDL_SCOPE lt_ptr_t (*lt_dlmalloc)LTDL_PARAMS((size_t size));
+LTDL_SCOPE void (*lt_dlfree)LTDL_PARAMS((lt_ptr_t ptr));
__END_DECLS