# HG changeset patch # User jwe # Date 819788977 0 # Node ID 913a157f1e02256a478fd0e7212690e6a8b902cd # Parent 00344209170c2eba3c34d9d66b5de874f6670456 [project @ 1995-12-24 07:00:22 by jwe] diff --git a/config.h.bot b/config.h.bot --- a/config.h.bot +++ b/config.h.bot @@ -4,3 +4,7 @@ #else #define NORETURN #endif + +#if defined (WITH_DL) || defined (WITH_SHL) || defined (WITH_DLD) +#define WITH_DYNAMIC_LINKING 1 +#endif diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -20,7 +20,7 @@ ### along with Octave; see the file COPYING. If not, write to the Free ### Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -AC_REVISION($Revision: 1.142 $) +AC_REVISION($Revision: 1.143 $) AC_PREREQ(2.0) AC_INIT(src/octave.cc) AC_CONFIG_HEADER(config.h) @@ -66,6 +66,23 @@ use_dld=false) AC_SUBST(use_dld) +### Allow the user to experiment with dynamic linking using dlopen/dlsym. + +AC_ARG_ENABLE(dl, + [ --enable-dl use dlopen/dlsym for dynamic linking (not all systems)], + [if test $enableval = no; then use_dl=false; else use_dl=true; fi], + use_dl=false) +AC_SUBST(use_dl) + +### Allow the user to experiment with dynamic linking using +### shl_load/shl_findsym (HP/UX only?). + +AC_ARG_ENABLE(shl, + [ --enable-shl use shl_load/shl_findsym for dynamic linking (HP only?)], + [if test $enableval = no; then use_shl=false; else use_shl=true; fi], + use_shl=false) +AC_SUBST(use_shl) + ### Allow compilation of smaller kernel. This only works if some form ### of dynamic linking is also supported and used. @@ -294,7 +311,7 @@ changequote(,)dnl 1.*|2.[012345].*) changequote([,])dnl - AC_MSG_WARN([g++ version $gxx_version will not work to compile Octave]) + AC_MSG_ERROR([g++ version $gxx_version will not work to compile Octave]) ;; *) AC_MSG_WARN([Octave has only been tested with g++, and I can't find it]) @@ -494,8 +511,7 @@ else AC_MSG_WARN([in order to build octave, you must have a compatible]) AC_MSG_WARN([Fortran compiler or f2c installed and in your path.]) - AC_MSG_WARN([See the file INSTALL for more information.]) - AC_MSG_WARN([Continuing anyway...]) + AC_MSG_ERROR([See the file INSTALL for more information.]) fi FC=$F77 @@ -585,6 +601,37 @@ AC_CHECK_FUNCS(mkdir rmdir rename umask) AC_CHECK_FUNCS(sigaction sigprocmask sigpending sigsuspend) +AC_CHECK_LIB(dl, dlopen) +AC_CHECK_FUNCS(dlopen dlsym dlerror dlclose) + +if test "$ac_cv_func_dlopen" = yes \ + && test "$ac_cv_func_dlopen" = yes \ + && test "$ac_cv_func_dlsym" = yes \ + && test "$ac_cv_func_dlerror" = yes \ + && test "$ac_cv_func_dlclose" = yes; then + use_dl=true +elif $use_dl; then + AC_MSG_ERROR([--enable-dl specified, but required functions are missing!]) +fi + +if $use_dl; then + AC_DEFINE(WITH_DL, 1) +fi + +AC_CHECK_LIB(dld, shl_load) +AC_CHECK_FUNCS(shl_load shl_findsym) + +if test "$ac_cv_func_shl_load" = yes \ + && test "$ac_cv_func_shl_findsym" = yes; then + use_shl=true +elif $use_shl; then + AC_MSG_ERROR([--enable-shl specified, but required functions are missing!]) +fi + +if $use_shl; then + AC_DEFINE(WITH_SHL, 1) +fi + ### There is more than one possible prototype for gettimeofday. See ### which one (if any) appears in sys/time.h. @@ -826,12 +873,8 @@ ### Do the substitutions in all the Makefiles. -define([tmpA], [Makefile octMakefile Makeconf])dnl -define([tmpB], [liboctave/Makefile src/Makefile dld/Makefile])dnl -define([tmpC], [doc/Makefile test/Makefile])dnl -define([srcdirs], [tmpA tmpB tmpC])dnl - -AC_OUTPUT([srcdirs]) +AC_OUTPUT(Makefile octMakefile Makeconf liboctave/Makefile + src/Makefile dld/Makefile doc/Makefile test/Makefile) ### Print a summary so that important information isn't missed. @@ -847,16 +890,19 @@ Octave is now configured for $canonical_host_type - Source directory: $srcdir - Installation prefix: $prefix - C compiler: $CC $GCC_IEEE_FP_FLAG $CFLAGS - C++ compiler: $CXX $CXX_EXTRAS $CXXFLAGS - Fortran compiler: $FORT - Fortran libraries: $FLIBS - Dynamic Linking: $use_dld - Minimal kernel option: $lite_kernel - Use GNU readline: $USE_READLINE - Use GNU info reader: $USE_GNU_INFO - Default pager: $DEFAULT_PAGER - gnuplot: $GNUPLOT_BINARY + Source directory: $srcdir + Installation prefix: $prefix + C compiler: $CC $GCC_IEEE_FP_FLAG $CFLAGS + C++ compiler: $CXX $CXX_EXTRAS $CXXFLAGS + Fortran compiler: $FORT + Fortran libraries: $FLIBS + Use GNU readline: $USE_READLINE + Use GNU info reader: $USE_GNU_INFO + Default pager: $DEFAULT_PAGER + gnuplot: $GNUPLOT_BINARY + + Minimal kernel option: $lite_kernel + Dynamic Linking (dld): $use_dld + Dynamic Linking (dlopen/dlsym): $use_dl + Dynamic Linking (shl_load/shl_findsym): $use_shl ]) diff --git a/src/dynamic-ld.cc b/src/dynamic-ld.cc --- a/src/dynamic-ld.cc +++ b/src/dynamic-ld.cc @@ -25,11 +25,20 @@ #include #endif +#if defined (WITH_SHL) +#include +#include +#endif + #include extern "C" { -#ifdef WITH_DLD +#if defined (WITH_DL) +#include +#elif defined (WITH_SHL) +#include +#elif defined (WITH_DLD) #include #endif } @@ -47,11 +56,120 @@ typedef builtin_function * (*Octave_builtin_fcn_struct_fcn)(void); +#if defined (WITH_DYNAMIC_LINKING) + +// XXX FIXME XXX -- need to provide some way to ensure that functions +// that we are going to use will use the same naming convention as +// Octave's internal functions. It needs to be simpler than the +// current DEFUN_DLD() macro, which assumes you know how to name the +// function, the struct, and the helper function. + +static char * +mangle_octave_builtin_name (const char *name) +{ + char *tmp = strconcat (name, "__FRC13Octave_objecti"); + char *retval = strconcat ("F", tmp); + delete [] tmp; + return retval; +} + +static char * +mangle_octave_oct_file_name (const char *name) +{ + char *tmp = strconcat (name, "__Fv"); + char *retval = strconcat ("FS", tmp); + delete [] tmp; + return retval; +} + +#endif + +#if defined (WITH_DL) + +static void * +dl_resolve_octave_reference (const char *name, const char *file) +{ + // Dynamic linking with dlopen/dlsym doesn't require specification + // of the libraries at runtime. Instead, they are specified when + // the .oct file is created. + + void *handle = dlopen (file, RTLD_LAZY); + + if (handle) + { + void *func = dlsym (handle, name); + + if (func) + return func; + else + { + const char *errmsg = dlerror (); + + if (errmsg) + error("%s: `%s'", name, errmsg); + else + error("unable to link function `%s'", name); + + dlclose (handle); + return 0; + } + } + else + { + error ("%s: %s `%s'", dlerror (), file, name); + return 0; + } +} + +#elif defined (WITH_SHL) + +static void * +shl_resolve_octave_reference (const char *name, const char *file) +{ + // Dynamic linking with shl_load/shl_findsym doesn't require + // specification of the libraries at runtime. Instead, they are + // specified when the .oct file is created. + + void *handle = shl_load (file, BIND_DEFERRED, 0L); + + if (handle) + { + void *func = 0; + + int status = shl_findsym ((shl_t *) &handle, name, + TYPE_UNDEFINED, func); + + if (status < 0) + { + const char *errmsg = strerror (errno); + + if (errmsg) + error("%s: `%s'", name, errmsg); + else + error("unable to link function `%s'", name); + + return 0; + } + else + return func; + } + else + { + error ("%s: %s `%s'", strerror (errno), file, name); + return 0; + } +} + +#elif defined (WITH_DLD) + +// Now that we have the code above to do dynamic linking with the +// dlopen/dlsym interface and Linux uses elf, I doubt that this code +// will be used very much. Maybe it will be able to go away +// eventually. Consider it unsupported... + // XXX FIXME XXX -- should this list be in a user-level variable, // with default taken from the environment? -#ifdef WITH_DLD - #ifndef STD_LIB_PATH #define STD_LIB_PATH "/lib:/usr/lib:/usr/local/lib" #endif @@ -77,24 +195,6 @@ static char *lib_list = OCTAVE_LIB_LIST ":" FLIB_LIST ":" SYSTEM_LIB_LIST; -static char * -mangle_octave_builtin_name (const char *name) -{ - char *tmp = strconcat (name, "__FRC13Octave_objecti"); - char *retval = strconcat ("F", tmp); - delete [] tmp; - return retval; -} - -static char * -mangle_octave_oct_file_name (const char *name) -{ - char *tmp = strconcat (name, "__Fv"); - char *retval = strconcat ("FS", tmp); - delete [] tmp; - return retval; -} - static void octave_dld_init (void) { @@ -143,7 +243,7 @@ } static void * -dld_octave_resolve_reference (const char *name, const char *file = 0) +dld_resolve_octave_reference (const char *name, const char *file) { dld_create_reference (name); @@ -151,7 +251,7 @@ { if (dld_link (file) != 0) { - error ("failed to link file %s", file); + error ("failed to link file `%s'", file); return 0; } @@ -194,23 +294,51 @@ return 0; } -static Octave_builtin_fcn -dld_octave_builtin (const char *name) +#endif + +static void * +resolve_octave_reference (const char *name, const char *file = 0) +{ +#if defined (WITH_DL) + + dl_resolve_octave_reference (name, file); + +#elif defined (WITH_SHL) + + shl_resolve_octave_reference (name, file); + +#elif defined (WITH_DLD) + + dld_resolve_octave_reference (name, file); + +#endif +} + +Octave_builtin_fcn +load_octave_builtin (const char *name) { Octave_builtin_fcn retval = 0; +#if defined (WITH_DYNAMIC_LINKING) + char *mangled_name = mangle_octave_builtin_name (name); - retval = (Octave_builtin_fcn) dld_octave_resolve_reference (mangled_name); + retval = (Octave_builtin_fcn) resolve_octave_reference (mangled_name); delete [] mangled_name; +#endif + return retval; } -static int -dld_octave_oct_file (const char *name) +int +load_octave_oct_file (const char *name) { + int retval = 0; + +#if defined (WITH_DYNAMIC_LINKING) + char *oct_file = oct_file_in_path (name); if (oct_file) @@ -218,7 +346,7 @@ char *mangled_name = mangle_octave_oct_file_name (name); Octave_builtin_fcn_struct_fcn f = - (Octave_builtin_fcn_struct_fcn) dld_octave_resolve_reference + (Octave_builtin_fcn_struct_fcn) resolve_octave_reference (mangled_name, oct_file); if (f) @@ -228,79 +356,32 @@ if (s) { install_builtin_function (s); - return 1; + retval = 1; } } delete [] oct_file; } - return 0; -} +#else + + (void) name; #endif -Octave_builtin_fcn -load_octave_builtin (const char *name) -{ -#ifdef WITH_DLD - return dld_octave_builtin (name); -#else - (void) name; - return 0; -#endif -} - -int -load_octave_oct_file (const char *name) -{ -#ifdef WITH_DLD - return dld_octave_oct_file (name); -#endif - (void) name; - return 0; + return retval; } void init_dynamic_linker (void) { -#ifdef WITH_DLD +#if defined (WITH_DLD) + octave_dld_init (); + #endif } -// OLD: - -#if 0 - -void -octave_dld_tc2_unlink_by_symbol (const char *name, int hard) -{ - // XXX FIXME XXX -- need to determine the name mangling scheme - // automatically, in case it changes, or is different on different - // systems, even if they have g++. - - char *mangled_fcn_name = strconcat (name, "__FRC13Octave_objecti"); - - int status = dld_unlink_by_symbol (mangled_fcn_name, hard); - - if (status != 0) - error ("octave_dld_tc2_unlink_by_symbol: %s", dld_strerror (0)); - - delete [] mangled_fcn_name; -} - -void -octave_dld_tc2_unlink_by_file (const char *name, int hard) -{ - int status = dld_unlink_by_file (name, hard); - - if (status != 0) - error ("octave_dld_tc2_unlink_by_file: %s", dld_strerror (0)); -} - -#endif - /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/src/dynamic-ld.h b/src/dynamic-ld.h --- a/src/dynamic-ld.h +++ b/src/dynamic-ld.h @@ -34,13 +34,6 @@ extern void init_dynamic_linker (void); -// OLD: - -#if 0 -extern void octave_dld_tc2_unlink_by_symbol (const char *name, int hard = 1); -extern void octave_dld_tc2_unlink_by_file (const char *name, int hard = 1); -#endif - #endif /* diff --git a/src/utils.cc b/src/utils.cc --- a/src/utils.cc +++ b/src/utils.cc @@ -370,7 +370,7 @@ while ((entry = readdir (dirp)) != 0) { int len = NLENGTH (entry); -#ifdef WITH_DLD +#if defined (WITH_DYNAMIC_LINKING) if ((len > 2 && entry->d_name[len-2] == '.' && entry->d_name[len-1] == 'm')