develooper Front page | perl.perl5.porters | Postings from January 2001

[PATCH: perl@8482] partial support for dynaloading on OS/390

Thread Next
From:
Peter Prymmer
Date:
January 19, 2001 18:09
Subject:
[PATCH: perl@8482] partial support for dynaloading on OS/390
Message ID:
Pine.OSF.4.10.10101191646420.61158-100000@aspara.forte.com

The following patch comes courtesy of the fine work done by John Goodyear
and the other folks at MSDW.  It adds one new dl_dllload.xs file to the
tar ball, but my suspicion is that the VM/ESA folks could set their hints
to let dlsrc='dl_dllload.xs' and that we may be able to get rid of the
dl_vmesa.xs file (Hello Neale?  Comments on that?)

Files affected:

  MANIFEST      # mention new file
  Makefile.SH   # extra GROK!THIS spit for new $DPERL_EXTERNAL_GLOB var
  ext/DynaLoader/dl_dllload.xs
  hints/os390.sh

folks wanting to follow along at home: you'll need GNU patch to apply this
but its almost not worth bothering just yet because of the previously
mentioned sprintf("%v",$^V) problem that messes up the build.
Nevertheless, until further tweaks are enacted static builds will still be
the default on OS/390.  I have verified that one can build a
statically linked patched 8482 kit (by manually tweaking configpm and
utils/perlbug.PL) and the resultant installed perl binary can still build
XS extensions such as OS390::Stdio.  I suspect that further work on
installation of the dynamic build will be necessary before we can switch
it over to being the default (among other things MakeMaker may require a
makeover). Nevertheless here is what's in store for dynamic loading and
shared libperl implementations: 

Size of static miniperl and libperl:

$ ls -l miniperl libperl*
-rw-r--r--   1 PVHP     OMVSGRP  3193598 Jan 19 15:33 libperl.a
-rwxr-xr-x   1 PVHP     OMVSGRP  3137536 Jan 19 15:34 miniperl

Size of dynamic miniperl and shared libperl:

$ ls -l miniperl libperl*
-rwxr-xr-x   1 PVHP     OMVSGRP  3809280 Jan 19 18:02 libperl.dll
-rw-r--r--   1 PVHP     OMVSGRP   122560 Jan 19 18:02 libperl.x
-rwxr-xr-x   1 PVHP     OMVSGRP   438272 Jan 19 18:02 miniperl

(and that might even be able to be reduced further).

Expect the usedl build to die in DynaLoader until MakeMaker is fixed.


diff -ruN perl.8482.orig/ext/DynaLoader/dl_dllload.xs perl.8482/ext/DynaLoader/dl_dllload.xs
--- perl.8482.orig/ext/DynaLoader/dl_dllload.xs	Wed Dec 31 16:00:00 1969
+++ perl.8482/ext/DynaLoader/dl_dllload.xs	Fri Jan 19 13:39:25 2001
@@ -0,0 +1,189 @@
+/* dl_dllload.xs
+ *
+ * Platform:	OS/390, possibly others that use dllload(),dllfree() (VM/ESA?).
+ * Authors:	John Goodyear && Peter Prymmer
+ * Created:     28 October 2000
+ * Modified:
+ * 16 January 2001 - based loosely on dl_dlopen.xs.
+ */
+ 
+/* Porting notes:
+
+   OS/390 Dynamic Loading functions: 
+
+   dllload
+   -------
+     dllhandle * dllload(const char *dllName)
+
+     This function takes the name of a dynamic object file and returns
+     a descriptor which can be used by dlllqueryfn() and/or dllqueryvar() 
+     later.  If dllName contains a slash, it is used to locate the dll.
+     If not then the LIBPATH environment variable is used to
+     search for the requested dll (at least within the HFS).
+     It returns NULL on error and sets errno.
+
+   dllfree
+   -------
+     int dllfree(dllhandle *handle);
+
+     dllfree() decrements the load count for the dll and frees
+     it if the count is 0.  It returns zero on success, and 
+     non-zero on failure.
+
+   dllqueryfn && dllqueryvar
+   -------------------------
+     void (* dllqueryfn(dllhandle *handle, const char *function))();
+     void * dllqueryvar(dllhandle *handle, const char *symbol);
+
+     dllqueryfn() takes the handle returned from dllload() and the name 
+     of a function to get the address of.  If the function was found 
+     a pointer is returned, otherwise NULL is returned.
+
+     dllqueryvar() takes the handle returned from dllload() and the name 
+     of a symbol to get the address of.  If the variable was found a 
+     pointer is returned, otherwise NULL is returned.
+
+     The XS dl_find_symbol() first calls dllqueryfn().  If it fails
+     dlqueryvar() is then called.
+
+   strerror
+   --------
+     char * strerror(int errno)
+
+     Returns a null-terminated string which describes the last error
+     that occurred with other functions (not necessarily unique to
+     dll loading).
+
+   Return Types
+   ============
+   In this implementation the two functions, dl_load_file() &&
+   dl_find_symbol(), return (void *).  This is primarily because the 
+   dlopen() && dlsym() style dynamic linker calls return (void *).
+   We suspect that casting to (void *) may be easier than teaching XS
+   typemaps about the (dllhandle *) type.
+
+   Dealing with Error Messages
+   ===========================
+   In order to make the handling of dynamic linking errors as generic as
+   possible you should store any error messages associated with your
+   implementation with the StoreError function.
+
+   In the case of OS/390 the function strerror(errno) returns the error 
+   message associated with the last dynamic link error.  As the S/390 
+   dynamic linker functions dllload() && dllqueryvar() both return NULL 
+   on error every call to an S/390 dynamic link routine is coded 
+   like this:
+
+	RETVAL = dllload(filename) ;
+	if (RETVAL == NULL)
+	    SaveError("%s",strerror(errno)) ;
+
+   Note that SaveError() takes a printf format string. Use a "%s" as
+   the first parameter if the error may contain any % characters.
+
+   Other comments within the dl_dlopen.xs file may be helpful as well.
+*/
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <dll.h>	/* the dynamic linker include file for S/390 */
+#include <errno.h>	/* strerror() and friends */
+
+#include "dlutils.c"	/* SaveError() etc */
+
+static void
+dl_private_init(pTHX)
+{
+    (void)dl_generic_private_init(aTHX);
+}
+
+MODULE = DynaLoader	PACKAGE = DynaLoader
+
+BOOT:
+    (void)dl_private_init(aTHX);
+
+
+void *
+dl_load_file(filename, flags=0)
+    char *	filename
+    int		flags
+  PREINIT:
+    int mode = 0;
+  CODE:
+{
+    DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
+    /* add a (void *) dllload(filename) ; cast if needed */
+    RETVAL = dllload(filename) ;
+    DLDEBUG(2,PerlIO_printf(Perl_debug_log, " libref=%lx\n", (unsigned long) RETVAL));
+    ST(0) = sv_newmortal() ;
+    if (RETVAL == NULL)
+	SaveError(aTHX_ "%s",strerror(errno)) ;
+    else
+	sv_setiv( ST(0), PTR2IV(RETVAL));
+}
+
+
+int
+dl_unload_file(libref)
+    void *	libref
+  CODE:
+    DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_unload_file(%lx):\n", PTR2ul(libref)));
+    /* RETVAL = (dllfree((dllhandle *)libref) == 0 ? 1 : 0); */
+    RETVAL = (dllfree(libref) == 0 ? 1 : 0);
+    if (!RETVAL)
+        SaveError(aTHX_ "%s", strerror(errno)) ;
+    DLDEBUG(2,PerlIO_printf(Perl_debug_log, " retval = %d\n", RETVAL));
+  OUTPUT:
+    RETVAL
+
+
+void *
+dl_find_symbol(libhandle, symbolname)
+    void *	libhandle
+    char *	symbolname
+    CODE:
+    DLDEBUG(2, PerlIO_printf(Perl_debug_log,
+			     "dl_find_symbol(handle=%lx, symbol=%s)\n",
+			     (unsigned long) libhandle, symbolname));
+    if((RETVAL = (void*)dllqueryfn(libhandle, symbolname)) == NULL)
+    RETVAL = dllqueryvar(libhandle, symbolname);
+    DLDEBUG(2, PerlIO_printf(Perl_debug_log,
+			     "  symbolref = %lx\n", (unsigned long) RETVAL));
+    ST(0) = sv_newmortal() ;
+    if (RETVAL == NULL)
+	SaveError(aTHX_ "%s",strerror(errno)) ;
+    else
+	sv_setiv( ST(0), PTR2IV(RETVAL));
+
+
+void
+dl_undef_symbols()
+    PPCODE:
+
+
+
+# These functions should not need changing on any platform:
+
+void
+dl_install_xsub(perl_name, symref, filename="$Package")
+    char *		perl_name
+    void *		symref 
+    char *		filename
+    CODE:
+    DLDEBUG(2,PerlIO_printf(Perl_debug_log, "dl_install_xsub(name=%s, symref=%lx)\n",
+		perl_name, (unsigned long) symref));
+    ST(0) = sv_2mortal(newRV((SV*)newXS(perl_name,
+					(void(*)(pTHX_ CV *))symref,
+					filename)));
+
+
+char *
+dl_error()
+    CODE:
+    RETVAL = LastError ;
+    OUTPUT:
+    RETVAL
+
+# end.
diff -ruN perl.8482.orig/hints/os390.sh perl.8482/hints/os390.sh
--- perl.8482.orig/hints/os390.sh	Wed Jan 17 07:58:03 2001
+++ perl.8482/hints/os390.sh	Fri Jan 19 12:36:41 2001
@@ -3,7 +3,8 @@
 # OS/390 hints by David J. Fiander <davidf@mks.com>
 #
 # OS/390 OpenEdition Release 3 Mon Sep 22 1997 thanks to:
-#     
+# 
+#     John Goodyear <johngood@us.ibm.com>
 #     John Pfuntner <pfuntner@vnet.ibm.com>
 #     Len Johnson <lenjay@ibm.net>
 #     Bud Huff  <BAHUFF@us.oracle.com>
@@ -42,27 +43,12 @@
 '') optimize='none' ;;
 esac
 
-# ccdlflags have yet to be determined.
-#case "$ccdlflags" in
-#'') ccdlflags='-c' ;;
-#esac
-
 # To link via definition side decks we need the dll option
 # You can override this with Configure -Ucccdlflags or somesuch.
 case "$cccdlflags" in
-'') cccdlflags='-W 0,dll,"langlvl(extended)"' ;;
+'') cccdlflags='-W 0,dll' ;;
 esac
 
-# ldflags have yet to be determined.
-#case "$ldflags" in
-#'') ldflags='' ;;
-#esac
-
-# lddlflags have yet to be determined.
-#case "$lddlflags" in
-#'') lddlflags='' ;;
-#esac
-
 case "$so" in
 '') so='a' ;;
 esac
@@ -83,17 +69,41 @@
 esac
 
 # Dynamic loading doesn't work on OS/390 quite yet.
-# You can override this with 
-#  Configure -Dusedl -Ddlext=.so -Ddlsrc=dl_dllload.xs.
+# However the easiest way to experiment with dynamic loading is with:
+#  Configure -Dusedl
+# You can even override some of this with things like:
+#  Configure -Dusedl -Ddlext=so -Ddlsrc=dl_dllload.xs.
 case "$usedl" in
-'') usedl='n' ;;
-esac
-case "$dlext" in
-'') dlext='none' ;;
+'')
+    usedl='n' 
+    case "$dlext" in
+    '') dlext='none' ;;
+    esac
+    ;;
+define)
+    case "$useshrplib" in
+    '') useshrplib='true' ;;
+    esac
+    case "$dlext" in
+    '') dlext='dll' ;;
+    esac
+    case "$dlsrc" in
+    '') dlsrc='dl_dllload.xs' ;;
+    esac
+    so='dll'
+    libperl='libperl.dll'
+    ccflags="$ccflags -D_SHR_ENVIRON -DPERL_EXTERNAL_GLOB -Wc,dll"
+    cccdlflags='-c -Wc,dll,EXPORTALL'
+    # You might add '-Wl,EDIT=NO' to get rid of the symbol
+    # information at the end of the executable.
+    #
+    # The following will need to be modified for the installed libperl.x
+    ccdlflags="-W l,dll `pwd`/libperl.x"
+    ldflags=''
+    lddlflags='-W l,dll'
+    ;;
 esac
-#case "$dlsrc" in
-#'') dlsrc='none' ;;
-#esac
+# even on static builds using LIBPATH should be OK.
 case "$ldlibpthname" in
 '') ldlibpthname=LIBPATH ;;
 esac
diff -ruN perl.8482.orig/Makefile.SH perl.8482/Makefile.SH
--- perl.8482.orig/Makefile.SH	Wed Jan 17 07:57:36 2001
+++ perl.8482/Makefile.SH	Fri Jan 19 12:40:32 2001
@@ -26,6 +26,7 @@
 linklibperl='$(LIBPERL)'
 shrpldflags='$(LDDLFLAGS)'
 ldlibpth=''
+DPERL_EXTERNAL_GLOB='-DPERL_EXTERNAL_GLOB'
 case "$useshrplib" in
 true)
 	# Prefix all runs of 'miniperl' and 'perl' with 
@@ -76,6 +77,10 @@
 	hpux*)
 		linklibperl="-L `pwd | sed 's/\/UU$//'` -Wl,+s -Wl,+b$archlibexp/CORE -lperl"
 		;;
+	os390*)
+	    linklibperl='libperl.x'
+	    DPERL_EXTERNAL_GLOB=''
+	    ;;
 	esac
 	case "$ldlibpthname" in
 	'') ;;
@@ -300,17 +305,21 @@
 # Apparently some makes require an action for the FORCE target.
 FORCE:
 	@sh -c true
+!NO!SUBS!
+$spitshell >>Makefile <<!GROK!THIS!
 
 # We do a copy of the op.c instead of a symlink because gcc gets huffy
 # if we have a symlink forest to another disk (it complains about too many
 # levels of symbolic links, even if we have only two)
 
-opmini$(OBJ_EXT): op.c config.h
-	$(RMS) opmini.c
-	$(CPS) op.c opmini.c
-	$(CCCMD) $(PLDLFLAGS) -DPERL_EXTERNAL_GLOB opmini.c
-	$(RMS) opmini.c
+opmini\$(OBJ_EXT): op.c config.h
+	\$(RMS) opmini.c
+	\$(CPS) op.c opmini.c
+	\$(CCCMD) \$(PLDLFLAGS) $DPERL_EXTERNAL_GLOB opmini.c
+	\$(RMS) opmini.c
 
+!GROK!THIS!
+$spitshell >>Makefile <<'!NO!SUBS!'
 miniperlmain$(OBJ_EXT): miniperlmain.c patchlevel.h
 	$(CCCMD) $(PLDLFLAGS) $*.c
 
diff -ruN perl.8482.orig/MANIFEST perl.8482/MANIFEST
--- perl.8482.orig/MANIFEST	Thu Dec 14 22:27:35 2000
+++ perl.8482/MANIFEST	Fri Jan 19 12:32:45 2001
@@ -176,6 +176,7 @@
 ext/DynaLoader/XSLoader_pm.PL	Simple XS Loader perl module
 ext/DynaLoader/dl_aix.xs	AIX implementation
 ext/DynaLoader/dl_beos.xs	BeOS implementation
+ext/DynaLoader/dl_dllload.xs	S/390 dllload() style implementation
 ext/DynaLoader/dl_dld.xs	GNU dld style implementation
 ext/DynaLoader/dl_dlopen.xs	BSD/SunOS4&5 dlopen() style implementation
 ext/DynaLoader/dl_dyld.xs	NeXT/Apple dyld implementation
End of Patch.

Peter Prymmer



Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About