From 62e6cfe58942a5ad17479f50213844599b49b9e6 Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Thu, 21 Jul 2005 21:22:58 +0000 Subject: drop support of ancient BSD, IRIX4, RISCos, Ultrix, and ldAout.tcl --- ChangeLog | 13 ++ library/ldAout.tcl | 233 ---------------------- unix/Makefile.in | 6 +- unix/configure | 502 +++------------------------------------------- unix/tcl.m4 | 228 ++++----------------- unix/tclLoadAout.c | 575 ----------------------------------------------------- 6 files changed, 88 insertions(+), 1469 deletions(-) delete mode 100644 library/ldAout.tcl delete mode 100644 unix/tclLoadAout.c diff --git a/ChangeLog b/ChangeLog index 3188acd..452433f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-07-21 Kevin B. Kenny + + * library/ldAout.tcl (***REMOVED***): Removed support for ancient + * unix/configure: BSD's, IRIX 4, RISCos and + * unix/Makefile.in: Ultrix. Removed two files + * unix/tcl.m4: whose code is used only on + * unix/tclLoadAout.c (***REMOVED***): those antique platforms. + + ***POTENTIAL INCOMPATIBILITY*** if anyone actually uses those + platforms; it is to be noted though, that an error in the + installer has actually not caused a necessary file to be installed + on those platforms in several releases, and nobody's complained. + 2005-07-16 Kevin B. Kenny * generic/tclStrToD.c (RefineResult): Plugged a stupid memory diff --git a/library/ldAout.tcl b/library/ldAout.tcl deleted file mode 100644 index c32f174..0000000 --- a/library/ldAout.tcl +++ /dev/null @@ -1,233 +0,0 @@ -# ldAout.tcl -- -# -# This "tclldAout" procedure in this script acts as a replacement -# for the "ld" command when linking an object file that will be -# loaded dynamically into Tcl or Tk using pseudo-static linking. -# -# Parameters: -# The arguments to the script are the command line options for -# an "ld" command. -# -# Results: -# The "ld" command is parsed, and the "-o" option determines the -# module name. ".a" and ".o" options are accumulated. -# The input archives and object files are examined with the "nm" -# command to determine whether the modules initialization -# entry and safe initialization entry are present. A trivial -# C function that locates the entries is composed, compiled, and -# its .o file placed before all others in the command; then -# "ld" is executed to bind the objects together. -# -# RCS: @(#) $Id: ldAout.tcl,v 1.6 2003/03/19 21:57:42 dgp Exp $ -# -# Copyright (c) 1995, by General Electric Company. All rights reserved. -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# This work was supported in part by the ARPA Manufacturing Automation -# and Design Engineering (MADE) Initiative through ARPA contract -# F33615-94-C-4400. - -proc tclLdAout {{cc {}} {shlib_suffix {}} {shlib_cflags none}} { - global env - global argv - - if {[string equal $cc ""]} { - set cc $env(CC) - } - - # if only two parameters are supplied there is assumed that the - # only shlib_suffix is missing. This parameter is anyway available - # as "info sharedlibextension" too, so there is no need to transfer - # 3 parameters to the function tclLdAout. For compatibility, this - # function now accepts both 2 and 3 parameters. - - if {[string equal $shlib_suffix ""]} { - set shlib_cflags $env(SHLIB_CFLAGS) - } elseif {[string equal $shlib_cflags "none"]} { - set shlib_cflags $shlib_suffix - } - - # seenDotO is nonzero if a .o or .a file has been seen - set seenDotO 0 - - # minusO is nonzero if the last command line argument was "-o". - set minusO 0 - - # head has command line arguments up to but not including the first - # .o or .a file. tail has the rest of the arguments. - set head {} - set tail {} - - # nmCommand is the "nm" command that lists global symbols from the - # object files. - set nmCommand {|nm -g} - - # entryProtos is the table of _Init and _SafeInit prototypes found in the - # module. - set entryProtos {} - - # entryPoints is the table of _Init and _SafeInit entries found in the - # module. - set entryPoints {} - - # libraries is the list of -L and -l flags to the linker. - set libraries {} - set libdirs {} - - # Process command line arguments - foreach a $argv { - if {!$minusO && [regexp {\.[ao]$} $a]} { - set seenDotO 1 - lappend nmCommand $a - } - if {$minusO} { - set outputFile $a - set minusO 0 - } elseif {![string compare $a -o]} { - set minusO 1 - } - if {[string match -nocase "-l*" $a]} { - lappend libraries $a - if {[string match "-L*" $a]} { - lappend libdirs [string range $a 2 end] - } - } elseif {$seenDotO} { - lappend tail $a - } else { - lappend head $a - } - } - lappend libdirs /lib /usr/lib - - # MIPS -- If there are corresponding G0 libraries, replace the - # ordinary ones with the G0 ones. - - set libs {} - foreach lib $libraries { - if {[string match "-l*" $lib]} { - set lname [string range $lib 2 end] - foreach dir $libdirs { - if {[file exists [file join $dir lib${lname}_G0.a]]} { - set lname ${lname}_G0 - break - } - } - lappend libs -l$lname - } else { - lappend libs $lib - } - } - set libraries $libs - - # Extract the module name from the "-o" option - - if {![info exists outputFile]} { - error "-o option must be supplied to link a Tcl load module" - } - set m [file tail $outputFile] - if {[regexp {\.a$} $outputFile]} { - set shlib_suffix .a - } else { - set shlib_suffix "" - } - if {[regexp {\..*$} $outputFile match]} { - set l [expr {[string length $m] - [string length $match]}] - } else { - error "Output file does not appear to have a suffix" - } - set modName [string tolower $m 0 [expr {$l-1}]] - if {[string match "lib*" $modName]} { - set modName [string range $modName 3 end] - } - if {[regexp {[0-9\.]*(_g0)?$} $modName match]} { - set modName [string range $modName 0 [expr {[string length $modName]-[string length $match]-1}]] - } - set modName [string totitle $modName] - - # Catalog initialization entry points found in the module - - set f [open $nmCommand r] - while {[gets $f l] >= 0} { - if {[regexp {T[ ]*_?([A-Z][a-z0-9_]*_(Safe)?Init(__FP10Tcl_Interp)?)$} $l trash symbol]} { - if {![regexp {_?([A-Z][a-z0-9_]*_(Safe)?Init)} $symbol trash s]} { - set s $symbol - } - append entryProtos {extern int } $symbol { (); } \n - append entryPoints { } \{ { "} $s {", } $symbol { } \} , \n - } - } - close $f - - if {[string equal $entryPoints ""]} { - error "No entry point found in objects" - } - - # Compose a C function that resolves the initialization entry points and - # embeds the required libraries in the object code. - - set C {#include } - append C \n - append C {char TclLoadLibraries_} $modName { [] =} \n - append C { "@LIBS: } $libraries {";} \n - append C $entryProtos - append C {static struct } \{ \n - append C { char * name;} \n - append C { int (*value)();} \n - append C \} {dictionary [] = } \{ \n - append C $entryPoints - append C { 0, 0 } \n \} \; \n - append C {typedef struct Tcl_Interp Tcl_Interp;} \n - append C {typedef int Tcl_PackageInitProc (Tcl_Interp *);} \n - append C {Tcl_PackageInitProc *} \n - append C TclLoadDictionary_ $modName { (symbol)} \n - append C { CONST char * symbol;} \n - append C { - { - int i; - for (i = 0; dictionary [i] . name != 0; ++i) { - if (!strcmp (symbol, dictionary [i] . name)) { - return dictionary [i].value; - } - } - return 0; - } - } - append C \n - - - # Write the C module and compile it - - set cFile tcl$modName.c - set f [open $cFile w] - puts -nonewline $f $C - close $f - set ccCommand "$cc -c $shlib_cflags $cFile" - puts stderr $ccCommand - eval exec $ccCommand - - # Now compose and execute the ld command that packages the module - - if {[string equal $shlib_suffix ".a"]} { - set ldCommand "ar cr $outputFile" - regsub { -o} $tail {} tail - } else { - set ldCommand ld - foreach item $head { - lappend ldCommand $item - } - } - lappend ldCommand tcl$modName.o - foreach item $tail { - lappend ldCommand $item - } - puts stderr $ldCommand - eval exec $ldCommand - if {[string equal $shlib_suffix ".a"]} { - exec ranlib $outputFile - } - - # Clean up working files - exec /bin/rm $cFile [file rootname $cFile].o -} diff --git a/unix/Makefile.in b/unix/Makefile.in index e47a89c..0875f19 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -5,7 +5,7 @@ # "autoconf" program (constructs like "@foo@" will get replaced in the # actual Makefile. # -# RCS: @(#) $Id: Makefile.in,v 1.171 2005/07/05 20:55:07 dgp Exp $ +# RCS: @(#) $Id: Makefile.in,v 1.172 2005/07/21 21:23:03 kennykb Exp $ VERSION = @TCL_VERSION@ MAJOR_VERSION = @TCL_MAJOR_VERSION@ @@ -502,7 +502,6 @@ NOTIFY_SRCS = \ DL_SRCS = \ $(UNIX_DIR)/tclLoadAix.c \ - $(UNIX_DIR)/tclLoadAout.c \ $(UNIX_DIR)/tclLoadDl.c \ $(UNIX_DIR)/tclLoadDl2.c \ $(UNIX_DIR)/tclLoadDld.c \ @@ -1028,9 +1027,6 @@ tclLoad.o: $(GENERIC_DIR)/tclLoad.c tclLoadAix.o: $(UNIX_DIR)/tclLoadAix.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadAix.c -tclLoadAout.o: $(UNIX_DIR)/tclLoadAout.c - $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadAout.c - tclLoadDl.o: $(UNIX_DIR)/tclLoadDl.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDl.c diff --git a/unix/configure b/unix/configure index 421b7cd..226b3eb 100755 --- a/unix/configure +++ b/unix/configure @@ -7052,18 +7052,6 @@ fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi ;; - IRIX-4.*) - SHLIB_CFLAGS="-G 0" - SHLIB_SUFFIX=".a" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" - SHLIB_LD_LIBS='${LIBS}' - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="$LDFLAGS -Wl,-D,08000000" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${VERSION}.a' - ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" @@ -7500,158 +7488,18 @@ fi LD_SEARCH_FLAGS="" ;; NetBSD-*|FreeBSD-[1-2].*) - # Not available on all versions: check for include file. - if test "${ac_cv_header_dlfcn_h+set}" = set; then - echo "$as_me:$LINENO: checking for dlfcn.h" >&5 -echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 -if test "${ac_cv_header_dlfcn_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 -echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 -echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 -echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for dlfcn.h" >&5 -echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 -if test "${ac_cv_header_dlfcn_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_dlfcn_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 -echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 - -fi -if test $ac_cv_header_dlfcn_h = yes; then - - # NetBSD/SPARC needs -fPIC, -fpic will not do. - SHLIB_CFLAGS="-fPIC" - SHLIB_LD="ld -Bshareable -x" - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' - echo "$as_me:$LINENO: checking for ELF" >&5 + # NetBSD/SPARC needs -fPIC, -fpic will not do. + SHLIB_CFLAGS="-fPIC" + SHLIB_LD="ld -Bshareable -x" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' + echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 - cat >conftest.$ac_ext <<_ACEOF + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -7667,70 +7515,40 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi rm -f conftest* -else - - SHLIB_CFLAGS="" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" - SHLIB_LD_LIBS='${LIBS}' - SHLIB_SUFFIX=".a" - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' - -fi - - - - # FreeBSD doesn't handle version numbers with dots. + # Ancient FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) - case `arch -s` in - m88k|vax) - SHLIB_CFLAGS="" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" - SHLIB_LD_LIBS='${LIBS}' - SHLIB_SUFFIX=".a" - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' - ;; + # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do. + case `machine` in + sparc|sparc64) + SHLIB_CFLAGS="-fPIC";; *) - # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do. - case `machine` in - sparc|sparc64) - SHLIB_CFLAGS="-fPIC";; - *) - SHLIB_CFLAGS="-fpic";; - esac - SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}" - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' - echo "$as_me:$LINENO: checking for ELF" >&5 + SHLIB_CFLAGS="-fpic";; + esac + SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' + echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6 - cat >conftest.$ac_ext <<_ACEOF + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -7746,17 +7564,15 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 - LDFLAGS=-Wl,-export-dynamic + LDFLAGS=-Wl,-export-dynamic else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 - LDFLAGS="" + LDFLAGS="" fi rm -f conftest* - ;; - esac # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' @@ -8469,17 +8285,6 @@ _ACEOF CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; - RISCos-*) - SHLIB_CFLAGS="-G 0" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" - SHLIB_LD_LIBS='${LIBS}' - SHLIB_SUFFIX=".a" - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="$LDFLAGS -Wl,-D,08000000" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and @@ -8646,20 +8451,6 @@ echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; - ULTRIX-4.*) - SHLIB_CFLAGS="-G 0" - SHLIB_SUFFIX=".a" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" - SHLIB_LD_LIBS='${LIBS}' - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="$LDFLAGS -Wl,-D,08000000" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "$GCC" != "yes" ; then - CFLAGS="$CFLAGS -DHAVE_TZSET -std1" - fi - ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="cc -G" @@ -8739,234 +8530,7 @@ _ACEOF fi - # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic - # Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop, - # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need - # to determine which of several header files defines the a.out file - # format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we - # support only a file format that is more or less version-7-compatible. - # In particular, - # - a.out files must begin with `struct exec'. - # - the N_TXTOFF on the `struct exec' must compute the seek address - # of the text segment - # - The `struct exec' must contain a_magic, a_text, a_data, a_bss - # and a_entry fields. - # The following compilation should succeed if and only if either sys/exec.h - # or a.out.h is usable for the purpose. - # - # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the - # `struct exec' includes a second header that contains information that - # duplicates the v7 fields that are needed. - - if test "x$DL_OBJS" = "xtclLoadAout.o" ; then - echo "$as_me:$LINENO: checking sys/exec.h" >&5 -echo $ECHO_N "checking sys/exec.h... $ECHO_C" >&6 - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - - struct exec foo; - unsigned long seek; - int flag; -#if defined(__mips) || defined(mips) - seek = N_TXTOFF (foo.ex_f, foo.ex_o); -#else - seek = N_TXTOFF (foo); -#endif - flag = (foo.a_magic == OMAGIC); - return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_ok=usable -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_ok=unusable -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - echo "$as_me:$LINENO: result: $tcl_ok" >&5 -echo "${ECHO_T}$tcl_ok" >&6 - if test $tcl_ok = usable; then - -cat >>confdefs.h <<\_ACEOF -#define USE_SYS_EXEC_H 1 -_ACEOF - - else - echo "$as_me:$LINENO: checking a.out.h" >&5 -echo $ECHO_N "checking a.out.h... $ECHO_C" >&6 - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - - struct exec foo; - unsigned long seek; - int flag; -#if defined(__mips) || defined(mips) - seek = N_TXTOFF (foo.ex_f, foo.ex_o); -#else - seek = N_TXTOFF (foo); -#endif - flag = (foo.a_magic == OMAGIC); - return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_ok=usable -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_ok=unusable -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - echo "$as_me:$LINENO: result: $tcl_ok" >&5 -echo "${ECHO_T}$tcl_ok" >&6 - if test $tcl_ok = usable; then - -cat >>confdefs.h <<\_ACEOF -#define USE_A_OUT_H 1 -_ACEOF - - else - echo "$as_me:$LINENO: checking sys/exec_aout.h" >&5 -echo $ECHO_N "checking sys/exec_aout.h... $ECHO_C" >&6 - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ - - struct exec foo; - unsigned long seek; - int flag; -#if defined(__mips) || defined(mips) - seek = N_TXTOFF (foo.ex_f, foo.ex_o); -#else - seek = N_TXTOFF (foo); -#endif - flag = (foo.a_midmag == OMAGIC); - return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_ok=usable -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_ok=unusable -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - echo "$as_me:$LINENO: result: $tcl_ok" >&5 -echo "${ECHO_T}$tcl_ok" >&6 - if test $tcl_ok = usable; then - -cat >>confdefs.h <<\_ACEOF -#define USE_SYS_EXEC_AOUT_H 1 -_ACEOF - - else - DL_OBJS="" - fi - fi - fi - fi - - # Step 5: disable dynamic loading if requested via a command-line switch. + # Step 4: disable dynamic loading if requested via a command-line switch. # Check whether --enable-load or --disable-load was given. if test "${enable_load+set}" = set; then diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 10335ad..92f29a3 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1135,18 +1135,6 @@ dnl AC_CHECK_TOOL(AR, ar) LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi ;; - IRIX-4.*) - SHLIB_CFLAGS="-G 0" - SHLIB_SUFFIX=".a" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" - SHLIB_LD_LIBS='${LIBS}' - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="$LDFLAGS -Wl,-D,08000000" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${VERSION}.a' - ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" @@ -1296,88 +1284,59 @@ dnl AC_CHECK_TOOL(AR, ar) LD_SEARCH_FLAGS="" ;; NetBSD-*|FreeBSD-[[1-2]].*) - # Not available on all versions: check for include file. - AC_CHECK_HEADER(dlfcn.h, [ - # NetBSD/SPARC needs -fPIC, -fpic will not do. - SHLIB_CFLAGS="-fPIC" - SHLIB_LD="ld -Bshareable -x" - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' - AC_MSG_CHECKING(for ELF) - AC_EGREP_CPP(yes, [ + # NetBSD/SPARC needs -fPIC, -fpic will not do. + SHLIB_CFLAGS="-fPIC" + SHLIB_LD="ld -Bshareable -x" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' + AC_MSG_CHECKING(for ELF) + AC_EGREP_CPP(yes, [ #ifdef __ELF__ yes #endif - ], - AC_MSG_RESULT(yes) - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so', - AC_MSG_RESULT(no) - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' - ) - ], [ - SHLIB_CFLAGS="" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" - SHLIB_LD_LIBS='${LIBS}' - SHLIB_SUFFIX=".a" - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' - ]) + ], + AC_MSG_RESULT(yes) + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so', + AC_MSG_RESULT(no) + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' + ) - # FreeBSD doesn't handle version numbers with dots. + # Ancient FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) - case `arch -s` in - m88k|vax) - SHLIB_CFLAGS="" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r" - SHLIB_LD_LIBS='${LIBS}' - SHLIB_SUFFIX=".a" - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' - ;; + # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do. + case `machine` in + sparc|sparc64) + SHLIB_CFLAGS="-fPIC";; *) - # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do. - case `machine` in - sparc|sparc64) - SHLIB_CFLAGS="-fPIC";; - *) - SHLIB_CFLAGS="-fpic";; - esac - SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}" - SHLIB_LD_LIBS="" - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' - AC_MSG_CHECKING(for ELF) - AC_EGREP_CPP(yes, [ + SHLIB_CFLAGS="-fpic";; + esac + SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' + AC_MSG_CHECKING(for ELF) + AC_EGREP_CPP(yes, [ #ifdef __ELF__ yes #endif - ], - AC_MSG_RESULT(yes) - [ LDFLAGS=-Wl,-export-dynamic ], - AC_MSG_RESULT(no) - LDFLAGS="" - ) - ;; - esac + ], + AC_MSG_RESULT(yes) + [ LDFLAGS=-Wl,-export-dynamic ], + AC_MSG_RESULT(no) + LDFLAGS="" + ) # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' @@ -1563,17 +1522,6 @@ dnl AC_CHECK_TOOL(AR, ar) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; - RISCos-*) - SHLIB_CFLAGS="-G 0" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" - SHLIB_LD_LIBS='${LIBS}' - SHLIB_SUFFIX=".a" - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="$LDFLAGS -Wl,-D,08000000" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and @@ -1723,20 +1671,6 @@ dnl AC_CHECK_TOOL(AR, ar) LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; - ULTRIX-4.*) - SHLIB_CFLAGS="-G 0" - SHLIB_SUFFIX=".a" - SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0" - SHLIB_LD_LIBS='${LIBS}' - DL_OBJS="tclLoadAout.o" - DL_LIBS="" - LDFLAGS="$LDFLAGS -Wl,-D,08000000" - CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "$GCC" != "yes" ; then - CFLAGS="$CFLAGS -DHAVE_TZSET -std1" - fi - ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="cc -G" @@ -1765,87 +1699,7 @@ dnl AC_CHECK_TOOL(AR, ar) AC_DEFINE(TCL_CFG_DO64BIT, 1, [Is this a 64-bit build?]) fi - # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic - # Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop, - # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need - # to determine which of several header files defines the a.out file - # format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we - # support only a file format that is more or less version-7-compatible. - # In particular, - # - a.out files must begin with `struct exec'. - # - the N_TXTOFF on the `struct exec' must compute the seek address - # of the text segment - # - The `struct exec' must contain a_magic, a_text, a_data, a_bss - # and a_entry fields. - # The following compilation should succeed if and only if either sys/exec.h - # or a.out.h is usable for the purpose. - # - # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the - # `struct exec' includes a second header that contains information that - # duplicates the v7 fields that are needed. - - if test "x$DL_OBJS" = "xtclLoadAout.o" ; then - AC_MSG_CHECKING(sys/exec.h) - AC_TRY_COMPILE([#include ],[ - struct exec foo; - unsigned long seek; - int flag; -#if defined(__mips) || defined(mips) - seek = N_TXTOFF (foo.ex_f, foo.ex_o); -#else - seek = N_TXTOFF (foo); -#endif - flag = (foo.a_magic == OMAGIC); - return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; - ], tcl_ok=usable, tcl_ok=unusable) - AC_MSG_RESULT($tcl_ok) - if test $tcl_ok = usable; then - AC_DEFINE(USE_SYS_EXEC_H, 1, - [Should we use when doing dynamic loading?]) - else - AC_MSG_CHECKING(a.out.h) - AC_TRY_COMPILE([#include ],[ - struct exec foo; - unsigned long seek; - int flag; -#if defined(__mips) || defined(mips) - seek = N_TXTOFF (foo.ex_f, foo.ex_o); -#else - seek = N_TXTOFF (foo); -#endif - flag = (foo.a_magic == OMAGIC); - return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; - ], tcl_ok=usable, tcl_ok=unusable) - AC_MSG_RESULT($tcl_ok) - if test $tcl_ok = usable; then - AC_DEFINE(USE_A_OUT_H, 1, - [Should we use when doing dynamic loading?]) - else - AC_MSG_CHECKING(sys/exec_aout.h) - AC_TRY_COMPILE([#include ],[ - struct exec foo; - unsigned long seek; - int flag; -#if defined(__mips) || defined(mips) - seek = N_TXTOFF (foo.ex_f, foo.ex_o); -#else - seek = N_TXTOFF (foo); -#endif - flag = (foo.a_midmag == OMAGIC); - return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry; - ], tcl_ok=usable, tcl_ok=unusable) - AC_MSG_RESULT($tcl_ok) - if test $tcl_ok = usable; then - AC_DEFINE(USE_SYS_EXEC_AOUT_H, 1, - [Should we use when doing dynamic loading?]) - else - DL_OBJS="" - fi - fi - fi - fi - - # Step 5: disable dynamic loading if requested via a command-line switch. + # Step 4: disable dynamic loading if requested via a command-line switch. AC_ARG_ENABLE(load, AC_HELP_STRING([--disable-load], diff --git a/unix/tclLoadAout.c b/unix/tclLoadAout.c deleted file mode 100644 index 7557a94..0000000 --- a/unix/tclLoadAout.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * tclLoadAout.c -- - * - * This procedure provides a version of the TclLoadFile that provides - * pseudo-static linking using version-7 compatible a.out files described - * in either sys/exec.h or sys/a.out.h. - * - * Copyright (c) 1995, by General Electric Company. All rights reserved. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * This work was supported in part by the ARPA Manufacturing Automation and - * Design Engineering (MADE) Initiative through ARPA contract - * F33615-94-C-4400. - * - * RCS: @(#) $Id: tclLoadAout.c,v 1.15 2005/07/19 13:37:18 dkf Exp $ - */ - -#include "tclInt.h" -#include -#ifdef HAVE_EXEC_AOUT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#else -# include "../compat/unistd.h" -#endif - -/* - * Some systems describe the a.out header in sys/exec.h, and some in a.out.h. - */ - -#ifdef USE_SYS_EXEC_H -#include -#endif -#ifdef USE_A_OUT_H -#include -#endif -#ifdef USE_SYS_EXEC_AOUT_H -#include -#define a_magic a_midmag -#endif - -/* - * TCL_LOADSHIM is the amount by which to shim the break when loading - */ - -#ifndef TCL_LOADSHIM -#define TCL_LOADSHIM 0x4000L -#endif - -/* - * TCL_LOADALIGN must be a power of 2, and is the alignment to which to force - * the origin of load modules - */ - -#ifndef TCL_LOADALIGN -#define TCL_LOADALIGN 0x4000L -#endif - -/* - * TCL_LOADMAX is the maximum size of a load module, and is used as a sanity - * check when loading - */ - -#ifndef TCL_LOADMAX -#define TCL_LOADMAX 2000000L -#endif - -/* - * Kernel calls that appear to be missing from the system .h files: - */ - -extern char * brk _ANSI_ARGS_((char *)); -extern char * sbrk _ANSI_ARGS_((size_t)); - -/* - * The static variable SymbolTableFile contains the file name where the result - * of the last link was stored. The file is kept because doing so allows one - * load module to use the symbols defined in another. - */ - -static char *SymbolTableFile = NULL; - -/* - * Type of the dictionary function that begins each load module. - */ - -typedef Tcl_PackageInitProc * (* DictFn) _ANSI_ARGS_((CONST char * symbol)); - -/* - * Prototypes for procedures referenced only in this file: - */ - -static int FindLibraries _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *pathPtr, Tcl_DString *buf)); -static void UnlinkSymbolTable _ANSI_ARGS_((void)); - -/* - *---------------------------------------------------------------------- - * - * TclpDlopen -- - * - * Dynamically loads a binary code file into memory and returns a handle - * to the new code. - * - * Results: - * A standard Tcl completion code. If an error occurs, an error message - * is left in the interp's result. - * - * Side effects: - * New code suddenly appears in memory. - * - * Bugs: - * This function does not attempt to handle the case where the BSS - * segment is not executable. It will therefore fail on Encore Multimax, - * Pyramid 90x, and similar machines. The reason is that the mprotect() - * kernel call, which would otherwise be employed to mark the - * newly-loaded text segment executable, results in a system crash on - * BSD/386. - * - * In an effort to make it fast, this function eschews the technique of - * linking the load module once, reading its header to determine its - * size, allocating memory for it, and linking it again. Instead, it - * `shims out' memory allocation by placing the module TCL_LOADSHIM bytes - * beyond the break, and assuming that any malloc() calls required to run - * the linker will not advance the break beyond that point. If the break - * is advanced beyonnd that point, the load will fail with an - * `inconsistent memory allocation' error. It perhaps ought to retry the - * link, but the failure has not been observed in two years of daily use - * of this function. - * - *---------------------------------------------------------------------- - */ - -int -TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr) - Tcl_Interp *interp; /* Used for error reporting. */ - Tcl_Obj *pathPtr; /* Name of the file containing the desired - * code (UTF-8). */ - Tcl_LoadHandle *loadHandle; /* Filled with token for dynamically loaded - * file which will be passed back to - * (*unloadProcPtr)() to unload the file. */ - Tcl_FSUnloadFileProc **unloadProcPtr; - /* Filled with address of Tcl_FSUnloadFileProc - * function which should be used for this - * file. */ -{ - char * inputSymbolTable; /* Name of the file containing the symbol - * table from the last link. */ - Tcl_DString linkCommandBuf; /* Command to do the run-time relocation of - * the module.*/ - char * linkCommand; - char relocatedFileName [L_tmpnam]; - /* Name of the file holding the relocated */ - /* text of the module */ - int relocatedFd; /* File descriptor of the file holding - * relocated text */ - struct exec relocatedHead; /* Header of the relocated text */ - unsigned long relocatedSize;/* Size of the relocated text */ - char * startAddress; /* Starting address of the module */ - int status; /* Status return from Tcl_ calls */ - char * p; - - /* - * Find the file that contains the symbols for the run-time link. - */ - - if (SymbolTableFile != NULL) { - inputSymbolTable = SymbolTableFile; - } else if (tclExecutableName == NULL) { - Tcl_SetResult(interp, "can't find the tclsh executable", TCL_STATIC); - return TCL_ERROR; - } else { - inputSymbolTable = tclExecutableName; - } - - /* - * Construct the `ld' command that builds the relocated module. - */ - - tmpnam(relocatedFileName); - Tcl_DStringInit(&linkCommandBuf); - Tcl_DStringAppend(&linkCommandBuf, "exec ld -o ", -1); - Tcl_DStringAppend(&linkCommandBuf, relocatedFileName, -1); -#if defined(__mips) || defined(mips) - Tcl_DStringAppend(&linkCommandBuf, " -G 0 ", -1); -#endif - Tcl_DStringAppend(&linkCommandBuf, " -u TclLoadDictionary_", -1); - TclGuessPackageName(Tcl_GetString(pathPtr), &linkCommandBuf); - Tcl_DStringAppend(&linkCommandBuf, " -A ", -1); - Tcl_DStringAppend(&linkCommandBuf, inputSymbolTable, -1); - Tcl_DStringAppend(&linkCommandBuf, " -N -T XXXXXXXX ", -1); - Tcl_DStringAppend(&linkCommandBuf, Tcl_GetString(pathPtr), -1); - Tcl_DStringAppend(&linkCommandBuf, " ", -1); - - if (FindLibraries(interp, pathPtr, &linkCommandBuf) != TCL_OK) { - Tcl_DStringFree(&linkCommandBuf); - return TCL_ERROR; - } - - linkCommand = Tcl_DStringValue(&linkCommandBuf); - - /* - * Determine the starting address, and plug it into the command. - */ - - startAddress = (char *) (((unsigned long) sbrk(0) - + TCL_LOADSHIM + TCL_LOADALIGN - 1) & (- TCL_LOADALIGN)); - p = strstr(linkCommand, "-T") + 3; - sprintf(p, "%08lx", (long) startAddress); - p[8] = ' '; - - /* - * Run the linker. - */ - - status = Tcl_Eval(interp, linkCommand); - Tcl_DStringFree(&linkCommandBuf); - if (status != 0) { - return TCL_ERROR; - } - - /* - * Open the linker's result file and read the header. - */ - - relocatedFd = open(relocatedFileName, O_RDONLY); - if (relocatedFd < 0) { - goto ioError; - } - status = read(relocatedFd, (char *) &relocatedHead, sizeof(relocatedHead)); - if (status < sizeof relocatedHead) { - goto ioError; - } - - /* - * Check the magic number. - */ - - if (relocatedHead.a_magic != OMAGIC) { - Tcl_AppendResult(interp, "bad magic number in intermediate file \"", - relocatedFileName, "\"", (char *) NULL); - goto failure; - } - - /* - * Make sure that memory allocation is still consistent. - */ - - if ((unsigned long) sbrk(0) > (unsigned long) startAddress) { - Tcl_SetResult(interp, "can't load, memory allocation is inconsistent.", - TCL_STATIC); - goto failure; - } - - /* - * Make sure that the relocated module's size is reasonable. - */ - - relocatedSize = relocatedHead.a_text + relocatedHead.a_data - + relocatedHead.a_bss; - if (relocatedSize > TCL_LOADMAX) { - Tcl_SetResult(interp, "module too big to load", TCL_STATIC); - goto failure; - } - - /* - * Advance the break to protect the loaded module. - */ - - (void) brk(startAddress + relocatedSize); - - /* - * Seek to the start of the module's text. - * - * Note that this does not really work with large files (i.e. where - * lseek64 exists and is different to lseek), but anyone trying to - * dynamically load a binary that is larger than what can fit in - * addressable memory is in trouble anyway... - */ - -#if defined(__mips) || defined(mips) - status = lseek(relocatedFd, - (off_t) N_TXTOFF(relocatedHead.ex_f, relocatedHead.ex_o), - SEEK_SET); -#else - status = lseek(relocatedFd, (off_t) N_TXTOFF (relocatedHead), SEEK_SET); -#endif - if (status < 0) { - goto ioError; - } - - /* - * Read in the module's text and data. - */ - - relocatedSize = relocatedHead.a_text + relocatedHead.a_data; - if (read(relocatedFd, startAddress, relocatedSize) < relocatedSize) { - brk(startAddress); - ioError: - Tcl_AppendResult(interp, "error on intermediate file \"", - relocatedFileName, "\": ", Tcl_PosixError(interp), - (char *) NULL); - failure: - (void) unlink(relocatedFileName); - return TCL_ERROR; - } - - /* - * Close the intermediate file. - */ - - (void) close(relocatedFd); - - /* - * Arrange things so that intermediate symbol tables eventually get - * deleted. - */ - - if (SymbolTableFile != NULL) { - UnlinkSymbolTable(); - } else { - atexit(UnlinkSymbolTable); - } - SymbolTableFile = ckalloc(strlen(relocatedFileName) + 1); - strcpy(SymbolTableFile, relocatedFileName); - - *loadHandle = startAddress; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclpFindSymbol -- - * - * Looks up a symbol, by name, through a handle associated with a - * previously loaded piece of code (shared library). - * - * Results: - * Returns a pointer to the function associated with 'symbol' if it is - * found. Otherwise returns NULL and may leave an error message in the - * interp's result. - * - *---------------------------------------------------------------------- - */ -Tcl_PackageInitProc* -TclpFindSymbol(interp, loadHandle, symbol) - Tcl_Interp *interp; - Tcl_LoadHandle loadHandle; - CONST char *symbol; -{ - /* - * Look up the entry point in the load module's dictionary. - */ - - DictFn dictionary = (DictFn) loadHandle; - - return (Tcl_PackageInitProc *) dictionary(sym1); -} - - -/* - *------------------------------------------------------------------------ - * - * FindLibraries -- - * - * Find the libraries needed to link a load module at run time. - * - * Results: - * A standard Tcl completion code. If an error occurs, an error message - * is left in the interp's result. The -l and -L flags are concatenated - * onto the dynamic string `buf'. - * - *------------------------------------------------------------------------ - */ - -static int -FindLibraries (interp, pathPtr, buf) - Tcl_Interp * interp; /* Used for error reporting */ - Tcl_Obj * pathPtr; /* Name of the load module */ - Tcl_DString * buf; /* Buffer where the -l an -L flags */ -{ - FILE * f; /* The load module */ - int c = 0; /* Byte from the load module */ - char * p; - CONST char *native; - - char *fileName = Tcl_GetString(pathPtr); - - /* - * Open the load module. - */ - - native = Tcl_FSGetNativePath(pathPtr); - f = fopen(native, "rb"); /* INTL: Native. */ - - if (f == NULL) { - Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ", - Tcl_PosixError(interp), (char *) NULL); - return TCL_ERROR; - } - - /* - * Search for the library list in the load module. - */ - - p = "@LIBS: "; - while (*p != '\0' && (c = getc(f)) != EOF) { - if (c == *p) { - ++p; - } else { - p = "@LIBS: "; - if (c == *p) { - ++p; - } - } - } - - /* - * No library list -- this must be an ill-formed module. - */ - - if (c == EOF) { - Tcl_AppendResult(interp, "File \"", fileName, - "\" is not a Tcl load module.", (char *) NULL); - (void) fclose(f); - return TCL_ERROR; - } - - /* - * Accumulate the library list. - */ - - while ((c = getc(f)) != '\0' && c != EOF) { - char cc = c; - Tcl_DStringAppend(buf, &cc, 1); - } - (void) fclose(f); - - if (c == EOF) { - Tcl_AppendResult(interp, "Library directory in \"", fileName, - "\" ends prematurely.", (char *) NULL); - return TCL_ERROR; - } - - return TCL_OK; -} - -/* - *------------------------------------------------------------------------ - * - * UnlinkSymbolTable -- - * - * Remove the symbol table file from the last dynamic link. - * - * Results: - * None. - * - * Side effects: - * The symbol table file from the last dynamic link is removed. This - * function is called when (a) a new symbol table is present because - * another dynamic link is complete, or (b) the process is exiting. - * - *------------------------------------------------------------------------ - */ - -static void -UnlinkSymbolTable() -{ - (void) unlink(SymbolTableFile); - ckfree(SymbolTableFile); - SymbolTableFile = NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TclpUnloadFile -- - * - * Unloads a dynamically loaded binary code file from memory. Code - * pointers in the formerly loaded file are no longer valid after calling - * this function. - * - * Results: - * None. - * - * Side effects: - * Does nothing. Can anything be done? - * - *---------------------------------------------------------------------- - */ - -void -TclpUnloadFile(loadHandle) - Tcl_LoadHandle loadHandle; /* loadHandle returned by a previous call to - * TclpDlopen(). The loadHandle is a token - * that represents the loaded file. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * TclGuessPackageName -- - * - * If the "load" command is invoked without providing a package name, - * this procedure is invoked to try to figure it out. - * - * Results: - * Always returns 0 to indicate that we couldn't figure out a package - * name; generic code will then try to guess the package from the file - * name. A return value of 1 would have meant that we figured out the - * package name and put it in bufPtr. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclGuessPackageName(fileName, bufPtr) - CONST char *fileName; /* Name of file containing package (already - * translated to local form if needed). */ - Tcl_DString *bufPtr; /* Initialized empty dstring. Append package - * name to this if possible. */ -{ - CONST char *p, *q; - char *r; - - if ((q = strrchr(fileName,'/'))) { - q++; - } else { - q = fileName; - } - if (!strncmp(q,"lib",3)) { - q+=3; - } - p = q; - while ((*p) && (*p != '.') && ((*p<'0') || (*p>'9'))) { - p++; - } - if ((p>q+2) && !strncmp(p-2,"_G0.",4)) { - p-=2; - } - if (p