From: Peter Prymmer Date: Fri, 19 Jan 2001 18:12:05 +0000 (-0800) Subject: partial support for dynaloading on OS/390 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ac9901e0f0bc12ad100c6e8b5f8bd40595e928ad;p=p5sagit%2Fp5-mst-13.2.git partial support for dynaloading on OS/390 Message-ID: p4raw-id: //depot/perl@8487 --- diff --git a/MANIFEST b/MANIFEST index 4269c3c..8b0d0f4 100644 --- a/MANIFEST +++ b/MANIFEST @@ -176,6 +176,7 @@ ext/DynaLoader/README Dynamic Loader notes and intro 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 diff --git a/Makefile.SH b/Makefile.SH index d0b5465..7a2ee11 100644 --- a/Makefile.SH +++ b/Makefile.SH @@ -26,6 +26,7 @@ esac 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 @@ true) 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 @@ utilities: miniperl lib/Config.pm $(plextract) lib/lib.pm FORCE # Apparently some makes require an action for the FORCE target. FORCE: @sh -c true +!NO!SUBS! +$spitshell >>Makefile <>Makefile <<'!NO!SUBS!' miniperlmain$(OBJ_EXT): miniperlmain.c patchlevel.h $(CCCMD) $(PLDLFLAGS) $*.c diff --git a/ext/DynaLoader/dl_dllload.xs b/ext/DynaLoader/dl_dllload.xs new file mode 100644 index 0000000..fe6957a --- /dev/null +++ b/ext/DynaLoader/dl_dllload.xs @@ -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 /* the dynamic linker include file for S/390 */ +#include /* 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 --git a/hints/os390.sh b/hints/os390.sh index 7a69634..ee75172 100644 --- a/hints/os390.sh +++ b/hints/os390.sh @@ -3,7 +3,8 @@ # OS/390 hints by David J. Fiander # # OS/390 OpenEdition Release 3 Mon Sep 22 1997 thanks to: -# +# +# John Goodyear # John Pfuntner # Len Johnson # Bud Huff @@ -42,27 +43,12 @@ case "$optimize" in '') 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 @@ case "$usenm" in 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' ;; -esac -#case "$dlsrc" in -#'') dlsrc='none' ;; -#esac +'') + 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 +# even on static builds using LIBPATH should be OK. case "$ldlibpthname" in '') ldlibpthname=LIBPATH ;; esac