blob: 3ca185f38adccb4eebbce9b459289e934539cdec [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
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Support for dynamic loading of extension modules */
26/* If no dynamic linking is supported, this file still generates some code! */
27
28#include "allobjects.h"
29#include "osdefs.h"
30#include "importdl.h"
31
Guido van Rossum1ae940a1995-01-02 19:04:15 +000032/* Explanation of some of the the various #defines used by dynamic linking...
33
34 symbol -- defined for:
35
36 DYNAMIC_LINK -- any kind of dynamic linking
Guido van Rossum75f288d1995-06-14 22:07:26 +000037 USE_RLD -- NeXT dynamic linking
Guido van Rossum1ae940a1995-01-02 19:04:15 +000038 USE_DL -- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
39 USE_SHLIB -- SunOS or IRIX 5 (SVR4?) shared libraries
40 _AIX -- AIX style dynamic linking
41 NT -- NT style dynamic linking (using DLLs)
Guido van Rossumdadc8241996-05-23 22:51:40 +000042 WIN16_DL -- Windows 16-bit dynamic linking (using DLLs)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000043 _DL_FUNCPTR_DEFINED -- if the typedef dl_funcptr has been defined
Jack Jansen5d9acb61995-06-14 14:54:25 +000044 USE_MAC_DYNAMIC_LOADING -- Mac CFM shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000045 SHORT_EXT -- short extension for dynamic module, e.g. ".so"
46 LONG_EXT -- long extension, e.g. "module.so"
47 hpux -- HP-UX Dynamic Linking - defined by the compiler
Guido van Rossum46c76a61995-01-20 16:53:54 +000048 __NetBSD__ -- NetBSD shared libraries (not quite SVR4 compatible)
Guido van Rossum25e85291996-02-25 05:02:29 +000049 __FreeBSD__ -- FreeBSD shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000050
51 (The other WITH_* symbols are used only once, to set the
52 appropriate symbols.)
53*/
54
55/* Configure dynamic linking */
56
Guido van Rossumff4af061996-01-12 01:17:50 +000057#ifdef __hpux
Guido van Rossum1e612491996-08-19 22:12:10 +000058#ifndef hpux
Guido van Rossumff4af061996-01-12 01:17:50 +000059#define hpux
60#endif
Guido van Rossum1e612491996-08-19 22:12:10 +000061#endif
Guido van Rossumff4af061996-01-12 01:17:50 +000062
Guido van Rossum1ae940a1995-01-02 19:04:15 +000063#ifdef hpux
64#define DYNAMIC_LINK
65#include <errno.h>
66typedef void (*dl_funcptr)();
67#define _DL_FUNCPTR_DEFINED 1
68#define SHORT_EXT ".sl"
69#define LONG_EXT "module.sl"
70#endif
71
Guido van Rossum25e85291996-02-25 05:02:29 +000072#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +000073#define DYNAMIC_LINK
74#define USE_SHLIB
75
76#define dlerror() "error in dynamic linking"
77#endif
78
Guido van Rossum0fbec641995-02-27 10:15:36 +000079#ifdef __WIN32__
80#define NT
81#endif
82
Guido van Rossumdadc8241996-05-23 22:51:40 +000083#ifdef MS_WIN16
84#define WIN16_DL
85#endif
86
87#if defined(NT) || defined(WIN16_DL)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000088#define DYNAMIC_LINK
89#include <windows.h>
90typedef FARPROC dl_funcptr;
91#define _DL_FUNCPTR_DEFINED
Guido van Rossum5fb1da71995-01-07 12:36:02 +000092#define SHORT_EXT ".pyd"
Guido van Rossume71a9471996-04-09 02:39:15 +000093#define LONG_EXT ".dll"
Guido van Rossum1ae940a1995-01-02 19:04:15 +000094#endif
95
Guido van Rossum75f288d1995-06-14 22:07:26 +000096#ifdef NeXT
Guido van Rossum1ae940a1995-01-02 19:04:15 +000097#define DYNAMIC_LINK
98#define USE_RLD
99#endif
100
101#ifdef WITH_SGI_DL
102#define DYNAMIC_LINK
103#define USE_DL
104#endif
105
106#ifdef WITH_DL_DLD
107#define DYNAMIC_LINK
108#define USE_DL
109#endif
110
Guido van Rossum1e612491996-08-19 22:12:10 +0000111#ifdef __powerc
112#define USE_MAC_DYNAMIC_LOADING
113#endif
114
Guido van Rossum6a75d261995-02-18 14:51:15 +0000115#ifdef __CFM68K__
Jack Jansen5d9acb61995-06-14 14:54:25 +0000116#define USE_MAC_DYNAMIC_LOADING
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000117#endif
118
Jack Jansen5d9acb61995-06-14 14:54:25 +0000119#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen4e043731995-02-13 22:42:34 +0000120#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000121#define SHORT_EXT ".slb"
Guido van Rossum1e612491996-08-19 22:12:10 +0000122#ifdef __CFM68K__
123#define LONG_EXT ".CFM68K.slb"
124#else
125#define LONG_EXT ".ppc.slb"
126#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000127#ifndef _DL_FUNCPTR_DEFINED
128typedef void (*dl_funcptr)();
129#endif
130#endif
131
Guido van Rossum1e612491996-08-19 22:12:10 +0000132#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && (defined(HAVE_DLOPEN) || defined(M_UNIX))
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000133#define DYNAMIC_LINK
134#define USE_SHLIB
135#endif
136
137#ifdef _AIX
138#define DYNAMIC_LINK
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000139#define SHORT_EXT ".so"
140#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000141#include <sys/ldr.h>
142typedef void (*dl_funcptr)();
143#define _DL_FUNCPTR_DEFINED
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000144static int aix_getoldmodules(void **);
145static int aix_bindnewmodule(void *, void *);
146static void aix_loaderror(char *);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000147#endif
148
149#ifdef DYNAMIC_LINK
150
151#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000152#include <sys/types.h>
153#include <sys/stat.h>
Guido van Rossum25e85291996-02-25 05:02:29 +0000154#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000155#include <nlist.h>
156#include <link.h>
157#else
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000158#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000159#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000160#ifndef _DL_FUNCPTR_DEFINED
161typedef void (*dl_funcptr)();
162#endif
163#ifndef RTLD_LAZY
164#define RTLD_LAZY 1
165#endif
166#define SHORT_EXT ".so"
167#define LONG_EXT "module.so"
168#endif /* USE_SHLIB */
169
170#if defined(USE_DL) || defined(hpux)
171#include "dl.h"
172#endif
173
Jack Jansen5d9acb61995-06-14 14:54:25 +0000174#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000175#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000176#include <CodeFragments.h>
Jack Janseneceb3e31995-06-27 13:15:15 +0000177#ifdef SYMANTEC__CFM68K__ /* Really just an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000178#define CFragConnectionID ConnectionID
179#define kLoadCFrag 0x01
180#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000181#include <Files.h>
182#include "macdefs.h"
183#include "macglue.h"
184#endif
185
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000186#ifdef USE_RLD
187#include <mach-o/rld.h>
188#define FUNCNAME_PATTERN "_init%.200s"
189#ifndef _DL_FUNCPTR_DEFINED
190typedef void (*dl_funcptr)();
191#endif
192#endif /* USE_RLD */
193
194extern char *getprogramname();
195
196#ifndef FUNCNAME_PATTERN
Guido van Rossum25e85291996-02-25 05:02:29 +0000197#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000198#define FUNCNAME_PATTERN "_init%.200s"
199#else
200#define FUNCNAME_PATTERN "init%.200s"
201#endif
202#endif
203
204#if !defined(SHORT_EXT) && !defined(LONG_EXT)
205#define SHORT_EXT ".o"
206#define LONG_EXT "module.o"
207#endif /* !SHORT_EXT && !LONG_EXT */
208
209#endif /* DYNAMIC_LINK */
210
Guido van Rossum6a75d261995-02-18 14:51:15 +0000211/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000212#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000213#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000214#endif
215
216/* Pass it on to import.c */
217int import_maxsuffixsize = MAXSUFFIXSIZE;
218
219struct filedescr import_filetab[] = {
220#ifdef SHORT_EXT
221 {SHORT_EXT, "rb", C_EXTENSION},
222#endif /* !SHORT_EXT */
223#ifdef LONG_EXT
224 {LONG_EXT, "rb", C_EXTENSION},
225#endif /* !LONG_EXT */
226 {".py", "r", PY_SOURCE},
227 {".pyc", "rb", PY_COMPILED},
228 {0, 0}
229};
230
Guido van Rossum38234201996-07-31 17:55:19 +0000231#ifdef NO_DYNAMIC_LINK
232#undef DYNAMIC_LINK
233#endif
234
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000235object *
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000236load_dynamic_module(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000237 char *name;
238 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000239 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000240{
241#ifndef DYNAMIC_LINK
242 err_setstr(ImportError, "dynamically linked modules not supported");
243 return NULL;
244#else
Guido van Rossum1e612491996-08-19 22:12:10 +0000245 object *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000246 char funcname[258];
247 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000248#ifdef USE_SHLIB
249 static struct {
250 dev_t dev;
251 ino_t ino;
252 void *handle;
253 } handles[128];
254 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000255 char pathbuf[260];
256 if (strchr(pathname, '/') == NULL) {
257 /* Prefix bare filename with "./" */
258 sprintf(pathbuf, "./%-.255s", pathname);
259 pathname = pathbuf;
260 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000261#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000262 sprintf(funcname, FUNCNAME_PATTERN, name);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000263#ifdef USE_SHLIB
264 if (fp != NULL) {
265 int i;
266 struct stat statb;
267 fstat(fileno(fp), &statb);
268 for (i = 0; i < nhandles; i++) {
269 if (statb.st_dev == handles[i].dev &&
270 statb.st_ino == handles[i].ino) {
271 p = (dl_funcptr) dlsym(handles[i].handle,
272 funcname);
273 goto got_it;
274 }
275 }
276 if (nhandles < 128) {
277 handles[nhandles].dev = statb.st_dev;
278 handles[nhandles].ino = statb.st_ino;
279 }
280 }
281#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000282#ifdef USE_MAC_DYNAMIC_LOADING
283 /*
284 ** Dynamic loading of CFM shared libraries on the Mac.
285 ** The code has become more convoluted than it was, because we want to be able
286 ** to put multiple modules in a single file. For this reason, we have to determine
287 ** the fragment name, and we cannot use the library entry point but we have to locate
288 ** the correct init routine "by hand".
289 */
Jack Jansen4e043731995-02-13 22:42:34 +0000290 {
291 FSSpec libspec;
292 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000293 Ptr mainAddr;
294 Str255 errMessage;
295 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000296 Boolean isfolder, didsomething;
297 char buf[512];
298 Str63 fragname;
299 Ptr symAddr;
300 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000301
Jack Jansen5d9acb61995-06-14 14:54:25 +0000302 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000303 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000304 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
305 if ( err ) {
306 sprintf(buf, "%s: %s", pathname, PyMac_StrError(err));
307 err_setstr(ImportError, buf);
308 return NULL;
309 }
310 /* Next, determine the fragment name, by stripping '.slb' and 'module' */
311 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
312 fragname[0] = libspec.name[0];
313 if( strncmp((char *)(fragname+1+fragname[0]-4), ".slb", 4) == 0 )
314 fragname[0] -= 4;
315 if ( strncmp((char *)(fragname+1+fragname[0]-6), "module", 6) == 0 )
316 fragname[0] -= 6;
317 /* Load the fragment (or return the connID if it is already loaded */
318 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000319 kLoadCFrag, &connID, &mainAddr,
320 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000321 if ( err ) {
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000322 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000323 err_setstr(ImportError, buf);
324 return NULL;
325 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000326 /* Locate the address of the correct init function */
327 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
328 if ( err ) {
329 sprintf(buf, "%s: %s", funcname, PyMac_StrError(err));
330 err_setstr(ImportError, buf);
331 return NULL;
332 }
333 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000334 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000335#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000336#ifdef USE_SHLIB
337 {
338#ifdef RTLD_NOW
339 /* RTLD_NOW: resolve externals now
340 (i.e. core dump now if some are missing) */
341 void *handle = dlopen(pathname, RTLD_NOW);
342#else
343 void *handle;
344 if (verbose)
345 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
346 handle = dlopen(pathname, RTLD_LAZY);
347#endif /* RTLD_NOW */
348 if (handle == NULL) {
349 err_setstr(ImportError, dlerror());
350 return NULL;
351 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000352 if (fp != NULL && nhandles < 128)
353 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000354 p = (dl_funcptr) dlsym(handle, funcname);
355 }
356#endif /* USE_SHLIB */
357#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000358 /*
359 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
360 -- of the shared module unresolved. Thus we have to resolve them
361 -- explicitely with loadbind. The new module is loaded, then we
362 -- resolve its symbols using the list of already loaded modules
363 -- (only those that belong to the python executable). Get these
364 -- with loadquery(L_GETINFO).
365 */
366 {
367 static void *staticmodlistptr = NULL;
368
369 if (!staticmodlistptr)
370 if (aix_getoldmodules(&staticmodlistptr) == -1)
371 return NULL;
372 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
373 if (p == NULL) {
374 aix_loaderror(pathname);
375 return NULL;
376 }
377 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
378 aix_loaderror(pathname);
379 return NULL;
380 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000381 }
382#endif /* _AIX */
383#ifdef NT
384 {
385 HINSTANCE hDLL;
386 hDLL = LoadLibrary(pathname);
387 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000388 char errBuf[256];
389 unsigned int errorCode;
390
391 /* Get an error string from Win32 error code */
392 char theInfo[256]; /* Pointer to error text from system */
393 int theLength; /* Length of error text */
394
395 errorCode = GetLastError();
396
397 theLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
398 NULL, /* message source */
399 errorCode, /* the message (error) ID */
400 0, /* default language environment */
401 (LPTSTR) theInfo, /* the buffer */
402 sizeof(theInfo), /* the buffer size */
403 NULL); /* no additional format args. */
404
405 /* Problem: could not get the error message. This should not happen if called correctly. */
406 if (theLength == 0) {
407 sprintf(errBuf, "DLL load failed with error code %d", errorCode);
408 } else {
409 int len;
410 /* For some reason a \r\n is appended to the text */
411 if (theLength >= 2 && theInfo[theLength-2] == '\r' && theInfo[theLength-1] == '\n') {
412 theLength -= 2;
413 theInfo[theLength] = '\0';
414 }
415 strcpy(errBuf, "DLL load failed: ");
416 len = strlen(errBuf);
417 strncpy(errBuf+len, theInfo, sizeof(errBuf)-len);
418 errBuf[sizeof(errBuf)-1] = '\0';
419 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000420 err_setstr(ImportError, errBuf);
421 return NULL;
422 }
423 p = GetProcAddress(hDLL, funcname);
424 }
425#endif /* NT */
Guido van Rossumdadc8241996-05-23 22:51:40 +0000426#ifdef WIN16_DL
427 {
428 HINSTANCE hDLL;
429 hDLL = LoadLibrary(pathname);
430 if (hDLL < HINSTANCE_ERROR){
431 char errBuf[256];
432 sprintf(errBuf, "DLL load failed with error code %d", hDLL);
433 err_setstr(ImportError, errBuf);
434 return NULL;
435 }
436 p = GetProcAddress(hDLL, funcname);
437 }
438#endif /* WIN16_DL */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000439#ifdef USE_DL
440 p = dl_loadmod(getprogramname(), pathname, funcname);
441#endif /* USE_DL */
442#ifdef USE_RLD
443 {
444 NXStream *errorStream;
445 struct mach_header *new_header;
446 const char *filenames[2];
447 long ret;
448 unsigned long ptr;
449
450 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
451 filenames[0] = pathname;
452 filenames[1] = NULL;
453 ret = rld_load(errorStream, &new_header,
454 filenames, NULL);
455
456 /* extract the error messages for the exception */
457 if(!ret) {
458 char *streamBuf;
459 int len, maxLen;
460
461 NXPutc(errorStream, (char)0);
462
463 NXGetMemoryBuffer(errorStream,
464 &streamBuf, &len, &maxLen);
465 err_setstr(ImportError, streamBuf);
466 }
467
468 if(ret && rld_lookup(errorStream, funcname, &ptr))
469 p = (dl_funcptr) ptr;
470
471 NXCloseMemory(errorStream, NX_FREEBUFFER);
472
473 if(!ret)
474 return NULL;
475 }
476#endif /* USE_RLD */
477#ifdef hpux
478 {
479 shl_t lib;
480 int flags;
481
482 flags = BIND_DEFERRED;
483 if (verbose)
484 {
485 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
486 printf("shl_load %s\n",pathname);
487 }
488 lib = shl_load(pathname, flags, 0);
489 if (lib == NULL)
490 {
491 char buf[256];
492 if (verbose)
493 perror(pathname);
494 sprintf(buf, "Failed to load %.200s", pathname);
495 err_setstr(ImportError, buf);
496 return NULL;
497 }
498 if (verbose)
499 printf("shl_findsym %s\n", funcname);
500 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
501 if (p == NULL && verbose)
502 perror(funcname);
503 }
504#endif /* hpux */
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000505 got_it:
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000506 if (p == NULL) {
507 err_setstr(ImportError,
508 "dynamic module does not define init function");
509 return NULL;
510 }
511 (*p)();
512
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000513 m = dictlookup(import_modules, name);
514 if (m == NULL) {
515 if (err_occurred() == NULL)
516 err_setstr(SystemError,
517 "dynamic module not initialized properly");
518 return NULL;
519 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000520 /* Remember the filename as the __file__ attribute */
521 d = getmoduledict(m);
522 s = newstringobject(pathname);
523 if (s == NULL || dictinsert(d, "__file__", s) != 0)
524 err_clear(); /* Not important enough to report */
525 XDECREF(s);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000526 if (verbose)
527 fprintf(stderr,
528 "import %s # dynamically loaded from %s\n",
529 name, pathname);
530 INCREF(m);
531 return m;
532#endif /* DYNAMIC_LINK */
533}
534
535
536#ifdef _AIX
537
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000538#include <ctype.h> /* for isdigit() */
539#include <errno.h> /* for global errno */
540#include <string.h> /* for strerror() */
541#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000542
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000543typedef struct Module {
544 struct Module *next;
545 void *entry;
546} Module, *ModulePtr;
547
548static int
549aix_getoldmodules(modlistptr)
550 void **modlistptr;
551{
552 register ModulePtr modptr, prevmodptr;
553 register struct ld_info *ldiptr;
554 register char *ldibuf;
555 register int errflag, bufsize = 1024;
556 register unsigned int offset;
557
558 /*
559 -- Get the list of loaded modules into ld_info structures.
560 */
561 if ((ldibuf = malloc(bufsize)) == NULL) {
562 err_setstr(ImportError, strerror(errno));
563 return -1;
564 }
565 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
566 && errno == ENOMEM) {
567 free(ldibuf);
568 bufsize += 1024;
569 if ((ldibuf = malloc(bufsize)) == NULL) {
570 err_setstr(ImportError, strerror(errno));
571 return -1;
572 }
573 }
574 if (errflag == -1) {
575 err_setstr(ImportError, strerror(errno));
576 return -1;
577 }
578 /*
579 -- Make the modules list from the ld_info structures.
580 */
581 ldiptr = (struct ld_info *)ldibuf;
582 prevmodptr = NULL;
583 do {
584 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
585 err_setstr(ImportError, strerror(errno));
586 while (*modlistptr) {
587 modptr = (ModulePtr)*modlistptr;
588 *modlistptr = (void *)modptr->next;
589 free(modptr);
590 }
591 return -1;
592 }
593 modptr->entry = ldiptr->ldinfo_dataorg;
594 modptr->next = NULL;
595 if (prevmodptr == NULL)
596 *modlistptr = (void *)modptr;
597 else
598 prevmodptr->next = modptr;
599 prevmodptr = modptr;
600 offset = (unsigned int)ldiptr->ldinfo_next;
601 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
602 } while (offset);
603 free(ldibuf);
604 return 0;
605}
606
607static int
608aix_bindnewmodule(newmoduleptr, modlistptr)
609 void *newmoduleptr;
610 void *modlistptr;
611{
612 register ModulePtr modptr;
613
614 /*
615 -- Bind the new module with the list of loaded modules.
616 */
617 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
618 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
619 return -1;
620 return 0;
621}
622
623static void
624aix_loaderror(pathname)
625 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000626{
627
Guido van Rossum236f62d1996-06-26 21:07:08 +0000628 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000629 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000630
631 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000632 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000633 char *errstr;
634 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000635 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000636 {L_ERROR_NOLIB, "can't load library:"},
637 {L_ERROR_UNDEF, "can't find symbol in library:"},
638 {L_ERROR_RLDBAD,
639 "RLD index out of range or bad relocation type:"},
640 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
641 {L_ERROR_MEMBER,
642 "file not an archive or does not contain requested member:"},
643 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000644 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000645 {L_ERROR_SYSTEM, "System error:"},
646 {L_ERROR_ERRNO, NULL}
647 };
648
649#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
650#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
651
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000652 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000653
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000654 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000655 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000656 ERRBUF_APPEND("\n");
657 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000658 for(i = 0; message[i] && *message[i]; i++) {
659 int nerr = atoi(message[i]);
660 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000661 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000662 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000663 }
664 while (isdigit(*message[i])) message[i]++ ;
665 ERRBUF_APPEND(message[i]);
666 ERRBUF_APPEND("\n");
667 }
668 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
669 err_setstr(ImportError, errbuf);
670 return;
671}
672
673#endif /* _AIX */