1Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH 2Not derived from licensed software. 3 4Permission is granted to freely use, copy, modify, and redistribute 5this software, provided that the author is not construed to be liable 6for any results of using the software, alterations are clearly marked 7as such, and this notice is not modified. 8 9libdl.a 10------- 11 12This is an emulation library to emulate the SunOS/System V.4 functions 13to access the runtime linker. The functions are emulated by using the 14AIX load() function and by reading the .loader section of the loaded 15module to find the exports. The to be loaded module should be linked as 16follows (if using AIX 3): 17 18 cc -o module.so -bM:SRE -bE:module.exp -e _nostart $(OBJS) 19 20For AIX 4: 21 22 cc -o module.so -bM:SRE -bE:module.exp -bnoentry $(OBJS) 23 24If you want to reference symbols from the main part of the program in a 25loaded module, you will have to link against the export file of the 26main part: 27 28 cc -o main -bE:main.exp $(MAIN_OBJS) 29 cc -o module.so -bM:SRE -bI:main.exp -bE:module.exp -bnoentry $(OBJS) 30 31Note that you explicitely have to specify what functions are supposed 32to be accessible from your loaded modules, this is different from 33SunOS/System V.4 where any global is automatically exported. If you 34want to export all globals, the following script might be of help: 35 36#!/bin/sh 37/usr/ucb/nm -g $* | awk '$2 == "B" || $2 == "D" { print $3 }' 38 39The module export file contains the symbols to be exported. Because 40this library uses the loader section, the final module.so file can be 41stripped. C++ users should build their shared objects using the script 42makeC++SharedLib (part of the IBM C++ compiler), this will make sure 43that constructors and destructors for static and global objects will be 44called upon loading and unloading the module. GNU C++ users should use 45the -shared option to g++ to link the shared object: 46 47 g++ -o module.so -shared $(OBJS) 48 49If the shared object does have permissions for anybody, the shared 50object will be loaded into the shared library segment and it will stay 51there even if the main application terminates. If you rebuild your 52shared object after a bugfix and you want to make sure that you really 53get the newest version you will have to use the "slibclean" command 54before starting the application again to garbage collect the shared 55library segment. If the performance utilities (bosperf) are installed 56you can use the following command to see what shared objects are 57loaded: 58 59/usr/lpp/bosperf/genkld | sort | uniq 60 61For easier debugging you can avoid loading the shared object into the 62shared library segment alltogether by removing permissions for others 63from the module.so file: 64 65chmod o-rwx module.so 66 67This will ensure you get a fresh copy of the shared object for every 68dlopen() call which is loaded into the application's data segment. 69 70Usage 71----- 72 73void *dlopen(const char *path, int mode); 74 75This routine loads the module pointed to by path and reads its export 76table. If the path does not contain a '/' character, dlopen will search 77for the module using the LIBPATH environment variable. It returns an 78opaque handle to the module or NULL on error. The mode parameter can be 79either RTLD_LAZY (for lazy function binding) or RTLD_NOW for immediate 80function binding. The AIX implementation currently does treat RTLD_NOW 81the same as RTLD_LAZY. The flag RTLD_GLOBAL might be or'ed into the 82mode parameter to allow loaded modules to bind to global variables or 83functions in other loaded modules loaded by dlopen(). If RTLD_GLOBAL is 84not specified, only globals from the main part of the executable or 85shared libraries are used to look for undefined symbols in loaded 86modules. 87 88 89void *dlsym(void *handle, const char *symbol); 90 91This routine searches for the symbol in the module referred to by 92handle and returns its address. If the symbol could not be found, the 93function returns NULL. The return value must be casted to a proper 94function pointer before it can be used. SunOS/System V.4 allows handle 95to be a NULL pointer to refer to the module the call is made from, this 96is not implemented. 97 98int dlclose(void *handle); 99 100This routine unloads the module referred to by the handle and disposes 101of any local storage. this function returns -1 on failure. Any function 102pointers obtained through dlsym() should be considered invalid after 103closing a module. 104 105As AIX caches shared objects in the shared library segment, function 106pointers obtained through dlsym() might still work even though the 107module has been unloaded. This can introduce subtle bugs that will 108segment fault later if AIX garbage collects or immediatly on 109SunOS/System V.4 as the text segment is unmapped. 110 111char *dlerror(void); 112 113This routine can be used to retrieve a text message describing the most 114recent error that occured on on of the above routines. This function 115returns NULL if there is no error information. 116 117Initialization and termination handlers 118--------------------------------------- 119 120The emulation provides for an initialization and a termination 121handler. The dlfcn.h file contains a structure declaration named 122dl_info with following members: 123 124 void (*init)(void); 125 void (*fini)(void); 126 127The init function is called upon first referencing the library. The 128fini function is called at dlclose() time or when the process exits. 129The module should declare a variable named dl_info that contains this 130structure which must be exported. These functions correspond to the 131documented _init() and _fini() functions of SunOS 4.x, but these are 132appearently not implemented in SunOS. When using SunOS 5.0, these 133correspond to #pragma init and #pragma fini respectively. At the same 134time any static or global C++ object's constructors or destructors will 135be called. 136 137BUGS 138---- 139 140Please note that there is currently a problem with implicitely loaded 141shared C++ libaries: if you refer to a shared C++ library from a loaded 142module that is not yet used by the main program, the dlopen() emulator 143does not notice this and does not call the static constructors for the 144implicitely loaded library. This can be easily demonstrated by 145referencing the C++ standard streams from a loaded module if the main 146program is a plain C program. 147 148Jens-Uwe Mager 149 150HELIOS Software GmbH 151Lavesstr. 80 15230159 Hannover 153Germany 154 155Phone: +49 511 36482-0 156FAX: +49 511 36482-69 157AppleLink: helios.de/jum 158Internet: jum@helios.de 159 160Revison History 161--------------- 162 163SCCS/s.dlfcn.h: 164 165D 1.4 95/04/25 09:36:52 jum 4 3 00018/00004/00028 166MRs: 167COMMENTS: 168added RTLD_GLOBAL, include and C++ guards 169 170D 1.3 92/12/27 20:58:32 jum 3 2 00001/00001/00031 171MRs: 172COMMENTS: 173we always have prototypes on RS/6000 174 175D 1.2 92/08/16 17:45:11 jum 2 1 00009/00000/00023 176MRs: 177COMMENTS: 178added dl_info structure to implement initialize and terminate functions 179 180D 1.1 92/08/02 18:08:45 jum 1 0 00023/00000/00000 181MRs: 182COMMENTS: 183Erstellungsdatum und -uhrzeit 92/08/02 18:08:45 von jum 184 185SCCS/s.dlfcn.c: 186 187D 1.11 96/04/10 20:12:51 jum 13 12 00037/00000/00533 188MRs: 189COMMENTS: 190Integrated the changes from John W. Eaton <jwe@bevo.che.wisc.edu> to initialize 191g++ generated shared objects. 192 193D 1.10 96/02/15 17:42:44 jum 12 10 00012/00007/00521 194MRs: 195COMMENTS: 196the C++ constructor and destructor chains are now called properly for either 197xlC 2 or xlC 3 (CSet++). 198 199D 1.9 95/09/22 11:09:38 markus 10 9 00001/00008/00527 200MRs: 201COMMENTS: 202Fix version number 203 204D 1.8 95/09/22 10:14:34 markus 9 8 00008/00001/00527 205MRs: 206COMMENTS: 207Added version number for dl lib 208 209D 1.7 95/08/14 19:08:38 jum 8 6 00026/00004/00502 210MRs: 211COMMENTS: 212Integrated the fixes from Kirk Benell (kirk@rsinc.com) to allow loading of 213shared objects generated under AIX 4. Fixed bug that symbols with exactly 2148 characters would use garbage characters from the following symbol value. 215 216D 1.6 95/04/25 09:38:03 jum 6 5 00046/00006/00460 217MRs: 218COMMENTS: 219added handling of C++ static constructors and destructors, added RTLD_GLOBAL to bind against other loaded modules 220 221D 1.5 93/02/14 20:14:17 jum 5 4 00002/00000/00464 222MRs: 223COMMENTS: 224added path to dlopen error message to make clear where there error occured. 225 226D 1.4 93/01/03 19:13:56 jum 4 3 00061/00005/00403 227MRs: 228COMMENTS: 229to allow calling symbols in the main module call load with L_NOAUTODEFER and 230do a loadbind later with the main module. 231 232D 1.3 92/12/27 20:59:55 jum 3 2 00066/00008/00342 233MRs: 234COMMENTS: 235added search by L_GETINFO if module got loaded by LIBPATH 236 237D 1.2 92/08/16 17:45:43 jum 2 1 00074/00006/00276 238MRs: 239COMMENTS: 240implemented initialize and terminate functions, added reference counting to avoid multiple loads of the same library 241 242D 1.1 92/08/02 18:08:45 jum 1 0 00282/00000/00000 243MRs: 244COMMENTS: 245Erstellungsdatum und -uhrzeit 92/08/02 18:08:45 von jum 246 247