blob: b9103746d3c3ae4ed1119716c2a5ff6fe4131338 [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 Rossum504f4a91996-08-20 19:59:07 +0000132#if !defined(DYNAMIC_LINK) && (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 Rossum504f4a91996-08-20 19:59:07 +0000158#ifdef HAVE_DLFCN_H
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000159#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000160#endif
Guido van Rossum504f4a91996-08-20 19:59:07 +0000161#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000162#ifndef _DL_FUNCPTR_DEFINED
163typedef void (*dl_funcptr)();
164#endif
165#ifndef RTLD_LAZY
166#define RTLD_LAZY 1
167#endif
168#define SHORT_EXT ".so"
169#define LONG_EXT "module.so"
170#endif /* USE_SHLIB */
171
172#if defined(USE_DL) || defined(hpux)
173#include "dl.h"
174#endif
175
Jack Jansen5d9acb61995-06-14 14:54:25 +0000176#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000177#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000178#include <CodeFragments.h>
Jack Janseneceb3e31995-06-27 13:15:15 +0000179#ifdef SYMANTEC__CFM68K__ /* Really just an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000180#define CFragConnectionID ConnectionID
181#define kLoadCFrag 0x01
182#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000183#include <Files.h>
184#include "macdefs.h"
185#include "macglue.h"
186#endif
187
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000188#ifdef USE_RLD
189#include <mach-o/rld.h>
190#define FUNCNAME_PATTERN "_init%.200s"
191#ifndef _DL_FUNCPTR_DEFINED
192typedef void (*dl_funcptr)();
193#endif
194#endif /* USE_RLD */
195
196extern char *getprogramname();
197
198#ifndef FUNCNAME_PATTERN
Guido van Rossum25e85291996-02-25 05:02:29 +0000199#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000200#define FUNCNAME_PATTERN "_init%.200s"
201#else
202#define FUNCNAME_PATTERN "init%.200s"
203#endif
204#endif
205
206#if !defined(SHORT_EXT) && !defined(LONG_EXT)
207#define SHORT_EXT ".o"
208#define LONG_EXT "module.o"
209#endif /* !SHORT_EXT && !LONG_EXT */
210
211#endif /* DYNAMIC_LINK */
212
Guido van Rossum6a75d261995-02-18 14:51:15 +0000213/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000214#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000215#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000216#endif
217
218/* Pass it on to import.c */
219int import_maxsuffixsize = MAXSUFFIXSIZE;
220
221struct filedescr import_filetab[] = {
222#ifdef SHORT_EXT
223 {SHORT_EXT, "rb", C_EXTENSION},
224#endif /* !SHORT_EXT */
225#ifdef LONG_EXT
226 {LONG_EXT, "rb", C_EXTENSION},
227#endif /* !LONG_EXT */
228 {".py", "r", PY_SOURCE},
229 {".pyc", "rb", PY_COMPILED},
230 {0, 0}
231};
232
Guido van Rossum38234201996-07-31 17:55:19 +0000233#ifdef NO_DYNAMIC_LINK
234#undef DYNAMIC_LINK
235#endif
236
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000237object *
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000238load_dynamic_module(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000239 char *name;
240 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000241 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000242{
243#ifndef DYNAMIC_LINK
244 err_setstr(ImportError, "dynamically linked modules not supported");
245 return NULL;
246#else
Guido van Rossum1e612491996-08-19 22:12:10 +0000247 object *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000248 char funcname[258];
249 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000250#ifdef USE_SHLIB
251 static struct {
252 dev_t dev;
253 ino_t ino;
254 void *handle;
255 } handles[128];
256 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000257 char pathbuf[260];
258 if (strchr(pathname, '/') == NULL) {
259 /* Prefix bare filename with "./" */
260 sprintf(pathbuf, "./%-.255s", pathname);
261 pathname = pathbuf;
262 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000263#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000264 sprintf(funcname, FUNCNAME_PATTERN, name);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000265#ifdef USE_SHLIB
266 if (fp != NULL) {
267 int i;
268 struct stat statb;
269 fstat(fileno(fp), &statb);
270 for (i = 0; i < nhandles; i++) {
271 if (statb.st_dev == handles[i].dev &&
272 statb.st_ino == handles[i].ino) {
273 p = (dl_funcptr) dlsym(handles[i].handle,
274 funcname);
275 goto got_it;
276 }
277 }
278 if (nhandles < 128) {
279 handles[nhandles].dev = statb.st_dev;
280 handles[nhandles].ino = statb.st_ino;
281 }
282 }
283#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000284#ifdef USE_MAC_DYNAMIC_LOADING
285 /*
286 ** Dynamic loading of CFM shared libraries on the Mac.
287 ** The code has become more convoluted than it was, because we want to be able
288 ** to put multiple modules in a single file. For this reason, we have to determine
289 ** the fragment name, and we cannot use the library entry point but we have to locate
290 ** the correct init routine "by hand".
291 */
Jack Jansen4e043731995-02-13 22:42:34 +0000292 {
293 FSSpec libspec;
294 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000295 Ptr mainAddr;
296 Str255 errMessage;
297 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000298 Boolean isfolder, didsomething;
299 char buf[512];
300 Str63 fragname;
301 Ptr symAddr;
302 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000303
Jack Jansen5d9acb61995-06-14 14:54:25 +0000304 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000305 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000306 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
307 if ( err ) {
308 sprintf(buf, "%s: %s", pathname, PyMac_StrError(err));
309 err_setstr(ImportError, buf);
310 return NULL;
311 }
312 /* Next, determine the fragment name, by stripping '.slb' and 'module' */
313 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
314 fragname[0] = libspec.name[0];
315 if( strncmp((char *)(fragname+1+fragname[0]-4), ".slb", 4) == 0 )
316 fragname[0] -= 4;
317 if ( strncmp((char *)(fragname+1+fragname[0]-6), "module", 6) == 0 )
318 fragname[0] -= 6;
319 /* Load the fragment (or return the connID if it is already loaded */
320 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000321 kLoadCFrag, &connID, &mainAddr,
322 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000323 if ( err ) {
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000324 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000325 err_setstr(ImportError, buf);
326 return NULL;
327 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000328 /* Locate the address of the correct init function */
329 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
330 if ( err ) {
331 sprintf(buf, "%s: %s", funcname, PyMac_StrError(err));
332 err_setstr(ImportError, buf);
333 return NULL;
334 }
335 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000336 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000337#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000338#ifdef USE_SHLIB
339 {
340#ifdef RTLD_NOW
341 /* RTLD_NOW: resolve externals now
342 (i.e. core dump now if some are missing) */
343 void *handle = dlopen(pathname, RTLD_NOW);
344#else
345 void *handle;
346 if (verbose)
347 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
348 handle = dlopen(pathname, RTLD_LAZY);
349#endif /* RTLD_NOW */
350 if (handle == NULL) {
351 err_setstr(ImportError, dlerror());
352 return NULL;
353 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000354 if (fp != NULL && nhandles < 128)
355 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000356 p = (dl_funcptr) dlsym(handle, funcname);
357 }
358#endif /* USE_SHLIB */
359#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000360 /*
361 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
362 -- of the shared module unresolved. Thus we have to resolve them
363 -- explicitely with loadbind. The new module is loaded, then we
364 -- resolve its symbols using the list of already loaded modules
365 -- (only those that belong to the python executable). Get these
366 -- with loadquery(L_GETINFO).
367 */
368 {
369 static void *staticmodlistptr = NULL;
370
371 if (!staticmodlistptr)
372 if (aix_getoldmodules(&staticmodlistptr) == -1)
373 return NULL;
374 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
375 if (p == NULL) {
376 aix_loaderror(pathname);
377 return NULL;
378 }
379 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
380 aix_loaderror(pathname);
381 return NULL;
382 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000383 }
384#endif /* _AIX */
385#ifdef NT
386 {
387 HINSTANCE hDLL;
388 hDLL = LoadLibrary(pathname);
389 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000390 char errBuf[256];
391 unsigned int errorCode;
392
393 /* Get an error string from Win32 error code */
394 char theInfo[256]; /* Pointer to error text from system */
395 int theLength; /* Length of error text */
396
397 errorCode = GetLastError();
398
399 theLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
400 NULL, /* message source */
401 errorCode, /* the message (error) ID */
402 0, /* default language environment */
403 (LPTSTR) theInfo, /* the buffer */
404 sizeof(theInfo), /* the buffer size */
405 NULL); /* no additional format args. */
406
407 /* Problem: could not get the error message. This should not happen if called correctly. */
408 if (theLength == 0) {
409 sprintf(errBuf, "DLL load failed with error code %d", errorCode);
410 } else {
411 int len;
412 /* For some reason a \r\n is appended to the text */
413 if (theLength >= 2 && theInfo[theLength-2] == '\r' && theInfo[theLength-1] == '\n') {
414 theLength -= 2;
415 theInfo[theLength] = '\0';
416 }
417 strcpy(errBuf, "DLL load failed: ");
418 len = strlen(errBuf);
419 strncpy(errBuf+len, theInfo, sizeof(errBuf)-len);
420 errBuf[sizeof(errBuf)-1] = '\0';
421 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000422 err_setstr(ImportError, errBuf);
423 return NULL;
424 }
425 p = GetProcAddress(hDLL, funcname);
426 }
427#endif /* NT */
Guido van Rossumdadc8241996-05-23 22:51:40 +0000428#ifdef WIN16_DL
429 {
430 HINSTANCE hDLL;
431 hDLL = LoadLibrary(pathname);
432 if (hDLL < HINSTANCE_ERROR){
433 char errBuf[256];
434 sprintf(errBuf, "DLL load failed with error code %d", hDLL);
435 err_setstr(ImportError, errBuf);
436 return NULL;
437 }
438 p = GetProcAddress(hDLL, funcname);
439 }
440#endif /* WIN16_DL */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000441#ifdef USE_DL
442 p = dl_loadmod(getprogramname(), pathname, funcname);
443#endif /* USE_DL */
444#ifdef USE_RLD
445 {
446 NXStream *errorStream;
447 struct mach_header *new_header;
448 const char *filenames[2];
449 long ret;
450 unsigned long ptr;
451
452 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
453 filenames[0] = pathname;
454 filenames[1] = NULL;
455 ret = rld_load(errorStream, &new_header,
456 filenames, NULL);
457
458 /* extract the error messages for the exception */
459 if(!ret) {
460 char *streamBuf;
461 int len, maxLen;
462
463 NXPutc(errorStream, (char)0);
464
465 NXGetMemoryBuffer(errorStream,
466 &streamBuf, &len, &maxLen);
467 err_setstr(ImportError, streamBuf);
468 }
469
470 if(ret && rld_lookup(errorStream, funcname, &ptr))
471 p = (dl_funcptr) ptr;
472
473 NXCloseMemory(errorStream, NX_FREEBUFFER);
474
475 if(!ret)
476 return NULL;
477 }
478#endif /* USE_RLD */
479#ifdef hpux
480 {
481 shl_t lib;
482 int flags;
483
484 flags = BIND_DEFERRED;
485 if (verbose)
486 {
487 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
488 printf("shl_load %s\n",pathname);
489 }
490 lib = shl_load(pathname, flags, 0);
491 if (lib == NULL)
492 {
493 char buf[256];
494 if (verbose)
495 perror(pathname);
496 sprintf(buf, "Failed to load %.200s", pathname);
497 err_setstr(ImportError, buf);
498 return NULL;
499 }
500 if (verbose)
501 printf("shl_findsym %s\n", funcname);
502 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
503 if (p == NULL && verbose)
504 perror(funcname);
505 }
506#endif /* hpux */
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000507 got_it:
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000508 if (p == NULL) {
509 err_setstr(ImportError,
510 "dynamic module does not define init function");
511 return NULL;
512 }
513 (*p)();
514
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000515 m = dictlookup(import_modules, name);
516 if (m == NULL) {
517 if (err_occurred() == NULL)
518 err_setstr(SystemError,
519 "dynamic module not initialized properly");
520 return NULL;
521 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000522 /* Remember the filename as the __file__ attribute */
523 d = getmoduledict(m);
524 s = newstringobject(pathname);
525 if (s == NULL || dictinsert(d, "__file__", s) != 0)
526 err_clear(); /* Not important enough to report */
527 XDECREF(s);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000528 if (verbose)
529 fprintf(stderr,
530 "import %s # dynamically loaded from %s\n",
531 name, pathname);
532 INCREF(m);
533 return m;
534#endif /* DYNAMIC_LINK */
535}
536
537
538#ifdef _AIX
539
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000540#include <ctype.h> /* for isdigit() */
541#include <errno.h> /* for global errno */
542#include <string.h> /* for strerror() */
543#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000544
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000545typedef struct Module {
546 struct Module *next;
547 void *entry;
548} Module, *ModulePtr;
549
550static int
551aix_getoldmodules(modlistptr)
552 void **modlistptr;
553{
554 register ModulePtr modptr, prevmodptr;
555 register struct ld_info *ldiptr;
556 register char *ldibuf;
557 register int errflag, bufsize = 1024;
558 register unsigned int offset;
559
560 /*
561 -- Get the list of loaded modules into ld_info structures.
562 */
563 if ((ldibuf = malloc(bufsize)) == NULL) {
564 err_setstr(ImportError, strerror(errno));
565 return -1;
566 }
567 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
568 && errno == ENOMEM) {
569 free(ldibuf);
570 bufsize += 1024;
571 if ((ldibuf = malloc(bufsize)) == NULL) {
572 err_setstr(ImportError, strerror(errno));
573 return -1;
574 }
575 }
576 if (errflag == -1) {
577 err_setstr(ImportError, strerror(errno));
578 return -1;
579 }
580 /*
581 -- Make the modules list from the ld_info structures.
582 */
583 ldiptr = (struct ld_info *)ldibuf;
584 prevmodptr = NULL;
585 do {
586 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
587 err_setstr(ImportError, strerror(errno));
588 while (*modlistptr) {
589 modptr = (ModulePtr)*modlistptr;
590 *modlistptr = (void *)modptr->next;
591 free(modptr);
592 }
593 return -1;
594 }
595 modptr->entry = ldiptr->ldinfo_dataorg;
596 modptr->next = NULL;
597 if (prevmodptr == NULL)
598 *modlistptr = (void *)modptr;
599 else
600 prevmodptr->next = modptr;
601 prevmodptr = modptr;
602 offset = (unsigned int)ldiptr->ldinfo_next;
603 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
604 } while (offset);
605 free(ldibuf);
606 return 0;
607}
608
609static int
610aix_bindnewmodule(newmoduleptr, modlistptr)
611 void *newmoduleptr;
612 void *modlistptr;
613{
614 register ModulePtr modptr;
615
616 /*
617 -- Bind the new module with the list of loaded modules.
618 */
619 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
620 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
621 return -1;
622 return 0;
623}
624
625static void
626aix_loaderror(pathname)
627 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000628{
629
Guido van Rossum236f62d1996-06-26 21:07:08 +0000630 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000631 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000632
633 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000634 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000635 char *errstr;
636 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000637 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000638 {L_ERROR_NOLIB, "can't load library:"},
639 {L_ERROR_UNDEF, "can't find symbol in library:"},
640 {L_ERROR_RLDBAD,
641 "RLD index out of range or bad relocation type:"},
642 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
643 {L_ERROR_MEMBER,
644 "file not an archive or does not contain requested member:"},
645 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000646 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000647 {L_ERROR_SYSTEM, "System error:"},
648 {L_ERROR_ERRNO, NULL}
649 };
650
651#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
652#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
653
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000654 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000655
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000656 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000657 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000658 ERRBUF_APPEND("\n");
659 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000660 for(i = 0; message[i] && *message[i]; i++) {
661 int nerr = atoi(message[i]);
662 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000663 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000664 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000665 }
666 while (isdigit(*message[i])) message[i]++ ;
667 ERRBUF_APPEND(message[i]);
668 ERRBUF_APPEND("\n");
669 }
670 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
671 err_setstr(ImportError, errbuf);
672 return;
673}
674
675#endif /* _AIX */