blob: 6541e09a5a03ac91a4feec3da1547ee051e1061a [file] [log] [blame]
Guido van Rossum1ae940a1995-01-02 19:04:15 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum1ae940a1995-01-02 19:04:15 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum1ae940a1995-01-02 19:04:15 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum1ae940a1995-01-02 19:04:15 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum1ae940a1995-01-02 19:04:15 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum1ae940a1995-01-02 19:04:15 +000029
30******************************************************************/
31
32/* Support for dynamic loading of extension modules */
33/* If no dynamic linking is supported, this file still generates some code! */
34
35#include "allobjects.h"
36#include "osdefs.h"
37#include "importdl.h"
38
Guido van Rossum1ae940a1995-01-02 19:04:15 +000039/* Explanation of some of the the various #defines used by dynamic linking...
40
41 symbol -- defined for:
42
43 DYNAMIC_LINK -- any kind of dynamic linking
Guido van Rossum75f288d1995-06-14 22:07:26 +000044 USE_RLD -- NeXT dynamic linking
Guido van Rossum1ae940a1995-01-02 19:04:15 +000045 USE_DL -- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
46 USE_SHLIB -- SunOS or IRIX 5 (SVR4?) shared libraries
47 _AIX -- AIX style dynamic linking
Guido van Rossum9b38a141996-09-11 23:12:24 +000048 MS_WIN32 -- Windows NT style dynamic linking (using DLLs)
49 MS_WIN16 -- Windows 16-bit dynamic linking (using DLLs)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000050 _DL_FUNCPTR_DEFINED -- if the typedef dl_funcptr has been defined
Jack Jansen5d9acb61995-06-14 14:54:25 +000051 USE_MAC_DYNAMIC_LOADING -- Mac CFM shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000052 SHORT_EXT -- short extension for dynamic module, e.g. ".so"
53 LONG_EXT -- long extension, e.g. "module.so"
54 hpux -- HP-UX Dynamic Linking - defined by the compiler
Guido van Rossum46c76a61995-01-20 16:53:54 +000055 __NetBSD__ -- NetBSD shared libraries (not quite SVR4 compatible)
Guido van Rossum25e85291996-02-25 05:02:29 +000056 __FreeBSD__ -- FreeBSD shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000057
58 (The other WITH_* symbols are used only once, to set the
59 appropriate symbols.)
60*/
61
62/* Configure dynamic linking */
63
Guido van Rossumff4af061996-01-12 01:17:50 +000064#ifdef __hpux
Guido van Rossum1e612491996-08-19 22:12:10 +000065#ifndef hpux
Guido van Rossumff4af061996-01-12 01:17:50 +000066#define hpux
67#endif
Guido van Rossum1e612491996-08-19 22:12:10 +000068#endif
Guido van Rossumff4af061996-01-12 01:17:50 +000069
Guido van Rossum1ae940a1995-01-02 19:04:15 +000070#ifdef hpux
71#define DYNAMIC_LINK
72#include <errno.h>
73typedef void (*dl_funcptr)();
74#define _DL_FUNCPTR_DEFINED 1
75#define SHORT_EXT ".sl"
76#define LONG_EXT "module.sl"
77#endif
78
Guido van Rossum25e85291996-02-25 05:02:29 +000079#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +000080#define DYNAMIC_LINK
81#define USE_SHLIB
82
83#define dlerror() "error in dynamic linking"
84#endif
85
Guido van Rossum9b38a141996-09-11 23:12:24 +000086#ifdef MS_WINDOWS /* i.e. MS_WIN32 or MS_WIN16 */
Guido van Rossum1ae940a1995-01-02 19:04:15 +000087#define DYNAMIC_LINK
88#include <windows.h>
89typedef FARPROC dl_funcptr;
90#define _DL_FUNCPTR_DEFINED
Guido van Rossum5fb1da71995-01-07 12:36:02 +000091#define SHORT_EXT ".pyd"
Guido van Rossume71a9471996-04-09 02:39:15 +000092#define LONG_EXT ".dll"
Guido van Rossum1ae940a1995-01-02 19:04:15 +000093#endif
94
Guido van Rossum75f288d1995-06-14 22:07:26 +000095#ifdef NeXT
Guido van Rossum1ae940a1995-01-02 19:04:15 +000096#define DYNAMIC_LINK
97#define USE_RLD
98#endif
99
100#ifdef WITH_SGI_DL
101#define DYNAMIC_LINK
102#define USE_DL
103#endif
104
105#ifdef WITH_DL_DLD
106#define DYNAMIC_LINK
107#define USE_DL
108#endif
109
Jack Jansen5d9acb61995-06-14 14:54:25 +0000110#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen4e043731995-02-13 22:42:34 +0000111#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000112#define SHORT_EXT ".slb"
Guido van Rossum1e612491996-08-19 22:12:10 +0000113#ifdef __CFM68K__
114#define LONG_EXT ".CFM68K.slb"
115#else
116#define LONG_EXT ".ppc.slb"
117#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000118#ifndef _DL_FUNCPTR_DEFINED
119typedef void (*dl_funcptr)();
120#endif
121#endif
122
Guido van Rossum504f4a91996-08-20 19:59:07 +0000123#if !defined(DYNAMIC_LINK) && (defined(HAVE_DLOPEN) || defined(M_UNIX))
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000124#define DYNAMIC_LINK
125#define USE_SHLIB
126#endif
127
128#ifdef _AIX
129#define DYNAMIC_LINK
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000130#define SHORT_EXT ".so"
131#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000132#include <sys/ldr.h>
133typedef void (*dl_funcptr)();
134#define _DL_FUNCPTR_DEFINED
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000135static int aix_getoldmodules(void **);
136static int aix_bindnewmodule(void *, void *);
137static void aix_loaderror(char *);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000138#endif
139
140#ifdef DYNAMIC_LINK
141
142#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000143#include <sys/types.h>
144#include <sys/stat.h>
Guido van Rossum25e85291996-02-25 05:02:29 +0000145#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000146#include <nlist.h>
147#include <link.h>
148#else
Guido van Rossum504f4a91996-08-20 19:59:07 +0000149#ifdef HAVE_DLFCN_H
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000150#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000151#endif
Guido van Rossum504f4a91996-08-20 19:59:07 +0000152#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000153#ifndef _DL_FUNCPTR_DEFINED
154typedef void (*dl_funcptr)();
155#endif
156#ifndef RTLD_LAZY
157#define RTLD_LAZY 1
158#endif
159#define SHORT_EXT ".so"
160#define LONG_EXT "module.so"
161#endif /* USE_SHLIB */
162
163#if defined(USE_DL) || defined(hpux)
164#include "dl.h"
165#endif
166
Jack Jansen5d9acb61995-06-14 14:54:25 +0000167#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000168#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000169#include <CodeFragments.h>
Jack Janseneceb3e31995-06-27 13:15:15 +0000170#ifdef SYMANTEC__CFM68K__ /* Really just an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000171#define CFragConnectionID ConnectionID
172#define kLoadCFrag 0x01
173#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000174#include <Files.h>
175#include "macdefs.h"
176#include "macglue.h"
177#endif
178
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000179#ifdef USE_RLD
180#include <mach-o/rld.h>
181#define FUNCNAME_PATTERN "_init%.200s"
182#ifndef _DL_FUNCPTR_DEFINED
183typedef void (*dl_funcptr)();
184#endif
185#endif /* USE_RLD */
186
187extern char *getprogramname();
188
189#ifndef FUNCNAME_PATTERN
Guido van Rossum25e85291996-02-25 05:02:29 +0000190#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000191#define FUNCNAME_PATTERN "_init%.200s"
192#else
193#define FUNCNAME_PATTERN "init%.200s"
194#endif
195#endif
196
197#if !defined(SHORT_EXT) && !defined(LONG_EXT)
198#define SHORT_EXT ".o"
199#define LONG_EXT "module.o"
200#endif /* !SHORT_EXT && !LONG_EXT */
201
202#endif /* DYNAMIC_LINK */
203
Guido van Rossum6a75d261995-02-18 14:51:15 +0000204/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000205#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000206#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000207#endif
208
209/* Pass it on to import.c */
210int import_maxsuffixsize = MAXSUFFIXSIZE;
211
212struct filedescr import_filetab[] = {
213#ifdef SHORT_EXT
214 {SHORT_EXT, "rb", C_EXTENSION},
215#endif /* !SHORT_EXT */
216#ifdef LONG_EXT
217 {LONG_EXT, "rb", C_EXTENSION},
218#endif /* !LONG_EXT */
219 {".py", "r", PY_SOURCE},
220 {".pyc", "rb", PY_COMPILED},
221 {0, 0}
222};
223
Guido van Rossum38234201996-07-31 17:55:19 +0000224#ifdef NO_DYNAMIC_LINK
225#undef DYNAMIC_LINK
226#endif
227
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000228object *
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000229load_dynamic_module(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000230 char *name;
231 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000232 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000233{
234#ifndef DYNAMIC_LINK
235 err_setstr(ImportError, "dynamically linked modules not supported");
236 return NULL;
237#else
Guido van Rossum1e612491996-08-19 22:12:10 +0000238 object *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000239 char funcname[258];
240 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000241#ifdef USE_SHLIB
242 static struct {
243 dev_t dev;
244 ino_t ino;
245 void *handle;
246 } handles[128];
247 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000248 char pathbuf[260];
249 if (strchr(pathname, '/') == NULL) {
250 /* Prefix bare filename with "./" */
251 sprintf(pathbuf, "./%-.255s", pathname);
252 pathname = pathbuf;
253 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000254#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000255 sprintf(funcname, FUNCNAME_PATTERN, name);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000256#ifdef USE_SHLIB
257 if (fp != NULL) {
258 int i;
259 struct stat statb;
260 fstat(fileno(fp), &statb);
261 for (i = 0; i < nhandles; i++) {
262 if (statb.st_dev == handles[i].dev &&
263 statb.st_ino == handles[i].ino) {
264 p = (dl_funcptr) dlsym(handles[i].handle,
265 funcname);
266 goto got_it;
267 }
268 }
269 if (nhandles < 128) {
270 handles[nhandles].dev = statb.st_dev;
271 handles[nhandles].ino = statb.st_ino;
272 }
273 }
274#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000275#ifdef USE_MAC_DYNAMIC_LOADING
276 /*
277 ** Dynamic loading of CFM shared libraries on the Mac.
278 ** The code has become more convoluted than it was, because we want to be able
279 ** to put multiple modules in a single file. For this reason, we have to determine
280 ** the fragment name, and we cannot use the library entry point but we have to locate
281 ** the correct init routine "by hand".
282 */
Jack Jansen4e043731995-02-13 22:42:34 +0000283 {
284 FSSpec libspec;
285 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000286 Ptr mainAddr;
287 Str255 errMessage;
288 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000289 Boolean isfolder, didsomething;
290 char buf[512];
291 Str63 fragname;
292 Ptr symAddr;
293 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000294
Jack Jansen5d9acb61995-06-14 14:54:25 +0000295 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000296 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000297 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
298 if ( err ) {
299 sprintf(buf, "%s: %s", pathname, PyMac_StrError(err));
300 err_setstr(ImportError, buf);
301 return NULL;
302 }
303 /* Next, determine the fragment name, by stripping '.slb' and 'module' */
304 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
305 fragname[0] = libspec.name[0];
306 if( strncmp((char *)(fragname+1+fragname[0]-4), ".slb", 4) == 0 )
307 fragname[0] -= 4;
308 if ( strncmp((char *)(fragname+1+fragname[0]-6), "module", 6) == 0 )
309 fragname[0] -= 6;
310 /* Load the fragment (or return the connID if it is already loaded */
311 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000312 kLoadCFrag, &connID, &mainAddr,
313 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000314 if ( err ) {
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000315 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000316 err_setstr(ImportError, buf);
317 return NULL;
318 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000319 /* Locate the address of the correct init function */
320 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
321 if ( err ) {
322 sprintf(buf, "%s: %s", funcname, PyMac_StrError(err));
323 err_setstr(ImportError, buf);
324 return NULL;
325 }
326 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000327 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000328#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000329#ifdef USE_SHLIB
330 {
331#ifdef RTLD_NOW
332 /* RTLD_NOW: resolve externals now
333 (i.e. core dump now if some are missing) */
334 void *handle = dlopen(pathname, RTLD_NOW);
335#else
336 void *handle;
337 if (verbose)
338 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
339 handle = dlopen(pathname, RTLD_LAZY);
340#endif /* RTLD_NOW */
341 if (handle == NULL) {
342 err_setstr(ImportError, dlerror());
343 return NULL;
344 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000345 if (fp != NULL && nhandles < 128)
346 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000347 p = (dl_funcptr) dlsym(handle, funcname);
348 }
349#endif /* USE_SHLIB */
350#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000351 /*
352 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
353 -- of the shared module unresolved. Thus we have to resolve them
354 -- explicitely with loadbind. The new module is loaded, then we
355 -- resolve its symbols using the list of already loaded modules
356 -- (only those that belong to the python executable). Get these
357 -- with loadquery(L_GETINFO).
358 */
359 {
360 static void *staticmodlistptr = NULL;
361
362 if (!staticmodlistptr)
363 if (aix_getoldmodules(&staticmodlistptr) == -1)
364 return NULL;
365 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
366 if (p == NULL) {
367 aix_loaderror(pathname);
368 return NULL;
369 }
370 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
371 aix_loaderror(pathname);
372 return NULL;
373 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000374 }
375#endif /* _AIX */
Guido van Rossum9b38a141996-09-11 23:12:24 +0000376#ifdef MS_WIN32
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000377 {
378 HINSTANCE hDLL;
379 hDLL = LoadLibrary(pathname);
380 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000381 char errBuf[256];
382 unsigned int errorCode;
383
384 /* Get an error string from Win32 error code */
385 char theInfo[256]; /* Pointer to error text from system */
386 int theLength; /* Length of error text */
387
388 errorCode = GetLastError();
389
390 theLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
391 NULL, /* message source */
392 errorCode, /* the message (error) ID */
393 0, /* default language environment */
394 (LPTSTR) theInfo, /* the buffer */
395 sizeof(theInfo), /* the buffer size */
396 NULL); /* no additional format args. */
397
398 /* Problem: could not get the error message. This should not happen if called correctly. */
399 if (theLength == 0) {
400 sprintf(errBuf, "DLL load failed with error code %d", errorCode);
401 } else {
402 int len;
403 /* For some reason a \r\n is appended to the text */
404 if (theLength >= 2 && theInfo[theLength-2] == '\r' && theInfo[theLength-1] == '\n') {
405 theLength -= 2;
406 theInfo[theLength] = '\0';
407 }
408 strcpy(errBuf, "DLL load failed: ");
409 len = strlen(errBuf);
410 strncpy(errBuf+len, theInfo, sizeof(errBuf)-len);
411 errBuf[sizeof(errBuf)-1] = '\0';
412 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000413 err_setstr(ImportError, errBuf);
414 return NULL;
415 }
416 p = GetProcAddress(hDLL, funcname);
417 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000418#endif /* MS_WIN32 */
419#ifdef MS_WIN16
Guido van Rossumdadc8241996-05-23 22:51:40 +0000420 {
421 HINSTANCE hDLL;
422 hDLL = LoadLibrary(pathname);
423 if (hDLL < HINSTANCE_ERROR){
424 char errBuf[256];
425 sprintf(errBuf, "DLL load failed with error code %d", hDLL);
426 err_setstr(ImportError, errBuf);
427 return NULL;
428 }
429 p = GetProcAddress(hDLL, funcname);
430 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000431#endif /* MS_WIN16 */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000432#ifdef USE_DL
433 p = dl_loadmod(getprogramname(), pathname, funcname);
434#endif /* USE_DL */
435#ifdef USE_RLD
436 {
437 NXStream *errorStream;
438 struct mach_header *new_header;
439 const char *filenames[2];
440 long ret;
441 unsigned long ptr;
442
443 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
444 filenames[0] = pathname;
445 filenames[1] = NULL;
446 ret = rld_load(errorStream, &new_header,
447 filenames, NULL);
448
449 /* extract the error messages for the exception */
450 if(!ret) {
451 char *streamBuf;
452 int len, maxLen;
453
454 NXPutc(errorStream, (char)0);
455
456 NXGetMemoryBuffer(errorStream,
457 &streamBuf, &len, &maxLen);
458 err_setstr(ImportError, streamBuf);
459 }
460
461 if(ret && rld_lookup(errorStream, funcname, &ptr))
462 p = (dl_funcptr) ptr;
463
464 NXCloseMemory(errorStream, NX_FREEBUFFER);
465
466 if(!ret)
467 return NULL;
468 }
469#endif /* USE_RLD */
470#ifdef hpux
471 {
472 shl_t lib;
473 int flags;
474
Guido van Rossum3afb5951996-12-05 23:15:35 +0000475 flags = BIND_FIRST | BIND_DEFERRED;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000476 if (verbose)
477 {
Guido van Rossum3afb5951996-12-05 23:15:35 +0000478 flags = DYNAMIC_PATH | BIND_FIRST | BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000479 printf("shl_load %s\n",pathname);
480 }
481 lib = shl_load(pathname, flags, 0);
482 if (lib == NULL)
483 {
484 char buf[256];
485 if (verbose)
486 perror(pathname);
487 sprintf(buf, "Failed to load %.200s", pathname);
488 err_setstr(ImportError, buf);
489 return NULL;
490 }
491 if (verbose)
492 printf("shl_findsym %s\n", funcname);
493 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
494 if (p == NULL && verbose)
495 perror(funcname);
496 }
497#endif /* hpux */
Guido van Rossum644a12b1997-04-09 19:24:53 +0000498#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000499 got_it:
Guido van Rossum644a12b1997-04-09 19:24:53 +0000500#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000501 if (p == NULL) {
502 err_setstr(ImportError,
503 "dynamic module does not define init function");
504 return NULL;
505 }
506 (*p)();
Guido van Rossum644a12b1997-04-09 19:24:53 +0000507 /* XXX Need check for err_occurred() here */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000508
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000509 m = dictlookup(import_modules, name);
510 if (m == NULL) {
511 if (err_occurred() == NULL)
512 err_setstr(SystemError,
513 "dynamic module not initialized properly");
514 return NULL;
515 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000516 /* Remember the filename as the __file__ attribute */
517 d = getmoduledict(m);
518 s = newstringobject(pathname);
519 if (s == NULL || dictinsert(d, "__file__", s) != 0)
520 err_clear(); /* Not important enough to report */
521 XDECREF(s);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000522 if (verbose)
523 fprintf(stderr,
524 "import %s # dynamically loaded from %s\n",
525 name, pathname);
526 INCREF(m);
527 return m;
528#endif /* DYNAMIC_LINK */
529}
530
531
532#ifdef _AIX
533
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000534#include <ctype.h> /* for isdigit() */
535#include <errno.h> /* for global errno */
536#include <string.h> /* for strerror() */
537#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000538
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000539typedef struct Module {
540 struct Module *next;
541 void *entry;
542} Module, *ModulePtr;
543
544static int
545aix_getoldmodules(modlistptr)
546 void **modlistptr;
547{
548 register ModulePtr modptr, prevmodptr;
549 register struct ld_info *ldiptr;
550 register char *ldibuf;
551 register int errflag, bufsize = 1024;
552 register unsigned int offset;
553
554 /*
555 -- Get the list of loaded modules into ld_info structures.
556 */
557 if ((ldibuf = malloc(bufsize)) == NULL) {
558 err_setstr(ImportError, strerror(errno));
559 return -1;
560 }
561 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
562 && errno == ENOMEM) {
563 free(ldibuf);
564 bufsize += 1024;
565 if ((ldibuf = malloc(bufsize)) == NULL) {
566 err_setstr(ImportError, strerror(errno));
567 return -1;
568 }
569 }
570 if (errflag == -1) {
571 err_setstr(ImportError, strerror(errno));
572 return -1;
573 }
574 /*
575 -- Make the modules list from the ld_info structures.
576 */
577 ldiptr = (struct ld_info *)ldibuf;
578 prevmodptr = NULL;
579 do {
580 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
581 err_setstr(ImportError, strerror(errno));
582 while (*modlistptr) {
583 modptr = (ModulePtr)*modlistptr;
584 *modlistptr = (void *)modptr->next;
585 free(modptr);
586 }
587 return -1;
588 }
589 modptr->entry = ldiptr->ldinfo_dataorg;
590 modptr->next = NULL;
591 if (prevmodptr == NULL)
592 *modlistptr = (void *)modptr;
593 else
594 prevmodptr->next = modptr;
595 prevmodptr = modptr;
596 offset = (unsigned int)ldiptr->ldinfo_next;
597 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
598 } while (offset);
599 free(ldibuf);
600 return 0;
601}
602
603static int
604aix_bindnewmodule(newmoduleptr, modlistptr)
605 void *newmoduleptr;
606 void *modlistptr;
607{
608 register ModulePtr modptr;
609
610 /*
611 -- Bind the new module with the list of loaded modules.
612 */
613 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
614 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
615 return -1;
616 return 0;
617}
618
619static void
620aix_loaderror(pathname)
621 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000622{
623
Guido van Rossum236f62d1996-06-26 21:07:08 +0000624 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000625 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000626
627 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000628 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000629 char *errstr;
630 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000631 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000632 {L_ERROR_NOLIB, "can't load library:"},
633 {L_ERROR_UNDEF, "can't find symbol in library:"},
634 {L_ERROR_RLDBAD,
635 "RLD index out of range or bad relocation type:"},
636 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
637 {L_ERROR_MEMBER,
638 "file not an archive or does not contain requested member:"},
639 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000640 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000641 {L_ERROR_SYSTEM, "System error:"},
642 {L_ERROR_ERRNO, NULL}
643 };
644
645#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
646#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
647
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000648 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000649
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000650 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000651 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000652 ERRBUF_APPEND("\n");
653 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000654 for(i = 0; message[i] && *message[i]; i++) {
655 int nerr = atoi(message[i]);
656 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000657 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000658 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000659 }
660 while (isdigit(*message[i])) message[i]++ ;
661 ERRBUF_APPEND(message[i]);
662 ERRBUF_APPEND("\n");
663 }
664 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
665 err_setstr(ImportError, errbuf);
666 return;
667}
668
669#endif /* _AIX */