3 * Platform: SunOS/Solaris, possibly others which use dlopen.
4 * Author: Paul Marquess (pmarquess@bfsec.bt.co.uk)
5 * Created: 10th July 1994
8 * 15th July 1994 - Added code to explicitly save any error messages.
9 * 3rd August 1994 - Upgraded to v3 spec.
10 * 9th August 1994 - Changed to use IV
11 * 10th August 1994 - Tim Bunce: Added RTLD_LAZY, switchable debugging,
12 * basic FreeBSD support, removed ClearError
19 Definition of Sunos dynamic Linking functions
20 =============================================
21 In order to make this implementation easier to understand here is a
22 quick definition of the SunOS Dynamic Linking functions which are
32 This function takes the name of a dynamic object file and returns
33 a descriptor which can be used by dlsym later. It returns NULL on
36 The mode parameter must be set to 1 for Solaris 1 and to
37 RTLD_LAZY (==2) on Solaris 2.
47 Takes the handle returned from dlopen and the name of a symbol to
48 get the address of. If the symbol was found a pointer is
49 returned. It returns NULL on error. If DL_PREPEND_UNDERSCORE is
50 defined an underscore will be added to the start of symbol. This
51 is required on some platforms (freebsd).
57 Returns a null-terminated string which describes the last error
58 that occurred with either dlopen or dlsym. After each call to
59 dlerror the error message will be reset to a null pointer. The
60 SaveError function is used to save the error as soo as it happens.
65 In this implementation the two functions, dl_load_file &
66 dl_find_symbol, return void *. This is because the underlying SunOS
67 dynamic linker calls also return void *. This is not necessarily
68 the case for all architectures. For example, some implementation
69 will want to return a char * for dl_load_file.
71 If void * is not appropriate for your architecture, you will have to
72 change the void * to whatever you require. If you are not certain of
73 how Perl handles C data types, I suggest you start by consulting
74 Dean Roerich's Perl 5 API document. Also, have a look in the typemap
75 file (in the ext directory) for a fairly comprehensive list of types
76 that are already supported. If you are completely stuck, I suggest you
77 post a message to perl5-porters, comp.lang.perl.misc or if you are really
80 Remember when you are making any changes that the return value from
81 dl_load_file is used as a parameter in the dl_find_symbol
82 function. Also the return value from find_symbol is used as a parameter
86 Dealing with Error Messages
87 ============================
88 In order to make the handling of dynamic linking errors as generic as
89 possible you should store any error messages associated with your
90 implementation with the StoreError function.
92 In the case of SunOS the function dlerror returns the error message
93 associated with the last dynamic link error. As the SunOS dynamic
94 linker functions dlopen & dlsym both return NULL on error every call
95 to a SunOS dynamic link routine is coded like this
97 RETVAL = dlopen(filename, 1) ;
99 SaveError("%s",dlerror()) ;
101 Note that SaveError() takes a printf format string. Use a "%s" as
102 the first parameter if the error may contain and % characters.
111 #include <dlfcn.h> /* the dynamic linker include file for Sunos/Solaris */
118 # define RTLD_LAZY 1 /* Solaris 1 */
123 # define dlerror() strerror(errno)
125 # define dlerror() "Unknown error - dlerror() not implemented"
130 #include "dlutils.c" /* SaveError() etc */
136 (void)dl_generic_private_init();
139 MODULE = DynaLoader PACKAGE = DynaLoader
142 (void)dl_private_init();
146 dl_load_file(filename, flags=0)
150 int mode = RTLD_LAZY;
160 warn("Can't make loaded symbols global on this platform while loading %s",filename);
162 DLDEBUG(1,PerlIO_printf(PerlIO_stderr(), "dl_load_file(%s,%x):\n", filename,flags));
163 RETVAL = dlopen(filename, mode) ;
164 DLDEBUG(2,PerlIO_printf(PerlIO_stderr(), " libref=%lx\n", (unsigned long) RETVAL));
165 ST(0) = sv_newmortal() ;
167 SaveError("%s",dlerror()) ;
169 sv_setiv( ST(0), (IV)RETVAL);
173 dl_find_symbol(libhandle, symbolname)
177 #ifdef DLSYM_NEEDS_UNDERSCORE
178 symbolname = form("_%s", symbolname);
180 DLDEBUG(2, PerlIO_printf(PerlIO_stderr(),
181 "dl_find_symbol(handle=%lx, symbol=%s)\n",
182 (unsigned long) libhandle, symbolname));
183 RETVAL = dlsym(libhandle, symbolname);
184 DLDEBUG(2, PerlIO_printf(PerlIO_stderr(),
185 " symbolref = %lx\n", (unsigned long) RETVAL));
186 ST(0) = sv_newmortal() ;
188 SaveError("%s",dlerror()) ;
190 sv_setiv( ST(0), (IV)RETVAL);
199 # These functions should not need changing on any platform:
202 dl_install_xsub(perl_name, symref, filename="$Package")
207 DLDEBUG(2,PerlIO_printf(PerlIO_stderr(), "dl_install_xsub(name=%s, symref=%lx)\n",
208 perl_name, (unsigned long) symref));
209 ST(0)=sv_2mortal(newRV((SV*)newXS(perl_name, (void(*)())symref, filename)));