blob: a8015ef08c53606ccb73e65f36b6a1a3fcf4f652 [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
Guido van Rossum9b38a141996-09-11 23:12:24 +000041 MS_WIN32 -- Windows NT style dynamic linking (using DLLs)
42 MS_WIN16 -- 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 Rossum9b38a141996-09-11 23:12:24 +000079#ifdef MS_WINDOWS /* i.e. MS_WIN32 or MS_WIN16 */
Guido van Rossum1ae940a1995-01-02 19:04:15 +000080#define DYNAMIC_LINK
81#include <windows.h>
82typedef FARPROC dl_funcptr;
83#define _DL_FUNCPTR_DEFINED
Guido van Rossum5fb1da71995-01-07 12:36:02 +000084#define SHORT_EXT ".pyd"
Guido van Rossume71a9471996-04-09 02:39:15 +000085#define LONG_EXT ".dll"
Guido van Rossum1ae940a1995-01-02 19:04:15 +000086#endif
87
Guido van Rossum75f288d1995-06-14 22:07:26 +000088#ifdef NeXT
Guido van Rossum1ae940a1995-01-02 19:04:15 +000089#define DYNAMIC_LINK
90#define USE_RLD
91#endif
92
93#ifdef WITH_SGI_DL
94#define DYNAMIC_LINK
95#define USE_DL
96#endif
97
98#ifdef WITH_DL_DLD
99#define DYNAMIC_LINK
100#define USE_DL
101#endif
102
Guido van Rossum1e612491996-08-19 22:12:10 +0000103#ifdef __powerc
104#define USE_MAC_DYNAMIC_LOADING
105#endif
106
Guido van Rossum6a75d261995-02-18 14:51:15 +0000107#ifdef __CFM68K__
Jack Jansen5d9acb61995-06-14 14:54:25 +0000108#define USE_MAC_DYNAMIC_LOADING
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000109#endif
110
Jack Jansen5d9acb61995-06-14 14:54:25 +0000111#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen4e043731995-02-13 22:42:34 +0000112#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000113#define SHORT_EXT ".slb"
Guido van Rossum1e612491996-08-19 22:12:10 +0000114#ifdef __CFM68K__
115#define LONG_EXT ".CFM68K.slb"
116#else
117#define LONG_EXT ".ppc.slb"
118#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000119#ifndef _DL_FUNCPTR_DEFINED
120typedef void (*dl_funcptr)();
121#endif
122#endif
123
Guido van Rossum504f4a91996-08-20 19:59:07 +0000124#if !defined(DYNAMIC_LINK) && (defined(HAVE_DLOPEN) || defined(M_UNIX))
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000125#define DYNAMIC_LINK
126#define USE_SHLIB
127#endif
128
129#ifdef _AIX
130#define DYNAMIC_LINK
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000131#define SHORT_EXT ".so"
132#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000133#include <sys/ldr.h>
134typedef void (*dl_funcptr)();
135#define _DL_FUNCPTR_DEFINED
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000136static int aix_getoldmodules(void **);
137static int aix_bindnewmodule(void *, void *);
138static void aix_loaderror(char *);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000139#endif
140
141#ifdef DYNAMIC_LINK
142
143#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000144#include <sys/types.h>
145#include <sys/stat.h>
Guido van Rossum25e85291996-02-25 05:02:29 +0000146#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000147#include <nlist.h>
148#include <link.h>
149#else
Guido van Rossum504f4a91996-08-20 19:59:07 +0000150#ifdef HAVE_DLFCN_H
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000151#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000152#endif
Guido van Rossum504f4a91996-08-20 19:59:07 +0000153#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000154#ifndef _DL_FUNCPTR_DEFINED
155typedef void (*dl_funcptr)();
156#endif
157#ifndef RTLD_LAZY
158#define RTLD_LAZY 1
159#endif
160#define SHORT_EXT ".so"
161#define LONG_EXT "module.so"
162#endif /* USE_SHLIB */
163
164#if defined(USE_DL) || defined(hpux)
165#include "dl.h"
166#endif
167
Jack Jansen5d9acb61995-06-14 14:54:25 +0000168#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000169#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000170#include <CodeFragments.h>
Jack Janseneceb3e31995-06-27 13:15:15 +0000171#ifdef SYMANTEC__CFM68K__ /* Really just an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000172#define CFragConnectionID ConnectionID
173#define kLoadCFrag 0x01
174#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000175#include <Files.h>
176#include "macdefs.h"
177#include "macglue.h"
178#endif
179
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000180#ifdef USE_RLD
181#include <mach-o/rld.h>
182#define FUNCNAME_PATTERN "_init%.200s"
183#ifndef _DL_FUNCPTR_DEFINED
184typedef void (*dl_funcptr)();
185#endif
186#endif /* USE_RLD */
187
188extern char *getprogramname();
189
190#ifndef FUNCNAME_PATTERN
Guido van Rossum25e85291996-02-25 05:02:29 +0000191#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000192#define FUNCNAME_PATTERN "_init%.200s"
193#else
194#define FUNCNAME_PATTERN "init%.200s"
195#endif
196#endif
197
198#if !defined(SHORT_EXT) && !defined(LONG_EXT)
199#define SHORT_EXT ".o"
200#define LONG_EXT "module.o"
201#endif /* !SHORT_EXT && !LONG_EXT */
202
203#endif /* DYNAMIC_LINK */
204
Guido van Rossum6a75d261995-02-18 14:51:15 +0000205/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000206#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000207#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000208#endif
209
210/* Pass it on to import.c */
211int import_maxsuffixsize = MAXSUFFIXSIZE;
212
213struct filedescr import_filetab[] = {
214#ifdef SHORT_EXT
215 {SHORT_EXT, "rb", C_EXTENSION},
216#endif /* !SHORT_EXT */
217#ifdef LONG_EXT
218 {LONG_EXT, "rb", C_EXTENSION},
219#endif /* !LONG_EXT */
220 {".py", "r", PY_SOURCE},
221 {".pyc", "rb", PY_COMPILED},
222 {0, 0}
223};
224
Guido van Rossum38234201996-07-31 17:55:19 +0000225#ifdef NO_DYNAMIC_LINK
226#undef DYNAMIC_LINK
227#endif
228
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000229object *
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000230load_dynamic_module(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000231 char *name;
232 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000233 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000234{
235#ifndef DYNAMIC_LINK
236 err_setstr(ImportError, "dynamically linked modules not supported");
237 return NULL;
238#else
Guido van Rossum1e612491996-08-19 22:12:10 +0000239 object *m, *d, *s;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000240 char funcname[258];
241 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000242#ifdef USE_SHLIB
243 static struct {
244 dev_t dev;
245 ino_t ino;
246 void *handle;
247 } handles[128];
248 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000249 char pathbuf[260];
250 if (strchr(pathname, '/') == NULL) {
251 /* Prefix bare filename with "./" */
252 sprintf(pathbuf, "./%-.255s", pathname);
253 pathname = pathbuf;
254 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000255#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000256 sprintf(funcname, FUNCNAME_PATTERN, name);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000257#ifdef USE_SHLIB
258 if (fp != NULL) {
259 int i;
260 struct stat statb;
261 fstat(fileno(fp), &statb);
262 for (i = 0; i < nhandles; i++) {
263 if (statb.st_dev == handles[i].dev &&
264 statb.st_ino == handles[i].ino) {
265 p = (dl_funcptr) dlsym(handles[i].handle,
266 funcname);
267 goto got_it;
268 }
269 }
270 if (nhandles < 128) {
271 handles[nhandles].dev = statb.st_dev;
272 handles[nhandles].ino = statb.st_ino;
273 }
274 }
275#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000276#ifdef USE_MAC_DYNAMIC_LOADING
277 /*
278 ** Dynamic loading of CFM shared libraries on the Mac.
279 ** The code has become more convoluted than it was, because we want to be able
280 ** to put multiple modules in a single file. For this reason, we have to determine
281 ** the fragment name, and we cannot use the library entry point but we have to locate
282 ** the correct init routine "by hand".
283 */
Jack Jansen4e043731995-02-13 22:42:34 +0000284 {
285 FSSpec libspec;
286 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000287 Ptr mainAddr;
288 Str255 errMessage;
289 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000290 Boolean isfolder, didsomething;
291 char buf[512];
292 Str63 fragname;
293 Ptr symAddr;
294 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000295
Jack Jansen5d9acb61995-06-14 14:54:25 +0000296 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000297 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000298 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
299 if ( err ) {
300 sprintf(buf, "%s: %s", pathname, PyMac_StrError(err));
301 err_setstr(ImportError, buf);
302 return NULL;
303 }
304 /* Next, determine the fragment name, by stripping '.slb' and 'module' */
305 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
306 fragname[0] = libspec.name[0];
307 if( strncmp((char *)(fragname+1+fragname[0]-4), ".slb", 4) == 0 )
308 fragname[0] -= 4;
309 if ( strncmp((char *)(fragname+1+fragname[0]-6), "module", 6) == 0 )
310 fragname[0] -= 6;
311 /* Load the fragment (or return the connID if it is already loaded */
312 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000313 kLoadCFrag, &connID, &mainAddr,
314 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000315 if ( err ) {
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000316 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000317 err_setstr(ImportError, buf);
318 return NULL;
319 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000320 /* Locate the address of the correct init function */
321 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
322 if ( err ) {
323 sprintf(buf, "%s: %s", funcname, PyMac_StrError(err));
324 err_setstr(ImportError, buf);
325 return NULL;
326 }
327 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000328 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000329#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000330#ifdef USE_SHLIB
331 {
332#ifdef RTLD_NOW
333 /* RTLD_NOW: resolve externals now
334 (i.e. core dump now if some are missing) */
335 void *handle = dlopen(pathname, RTLD_NOW);
336#else
337 void *handle;
338 if (verbose)
339 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
340 handle = dlopen(pathname, RTLD_LAZY);
341#endif /* RTLD_NOW */
342 if (handle == NULL) {
343 err_setstr(ImportError, dlerror());
344 return NULL;
345 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000346 if (fp != NULL && nhandles < 128)
347 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000348 p = (dl_funcptr) dlsym(handle, funcname);
349 }
350#endif /* USE_SHLIB */
351#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000352 /*
353 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
354 -- of the shared module unresolved. Thus we have to resolve them
355 -- explicitely with loadbind. The new module is loaded, then we
356 -- resolve its symbols using the list of already loaded modules
357 -- (only those that belong to the python executable). Get these
358 -- with loadquery(L_GETINFO).
359 */
360 {
361 static void *staticmodlistptr = NULL;
362
363 if (!staticmodlistptr)
364 if (aix_getoldmodules(&staticmodlistptr) == -1)
365 return NULL;
366 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
367 if (p == NULL) {
368 aix_loaderror(pathname);
369 return NULL;
370 }
371 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
372 aix_loaderror(pathname);
373 return NULL;
374 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000375 }
376#endif /* _AIX */
Guido van Rossum9b38a141996-09-11 23:12:24 +0000377#ifdef MS_WIN32
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000378 {
379 HINSTANCE hDLL;
380 hDLL = LoadLibrary(pathname);
381 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000382 char errBuf[256];
383 unsigned int errorCode;
384
385 /* Get an error string from Win32 error code */
386 char theInfo[256]; /* Pointer to error text from system */
387 int theLength; /* Length of error text */
388
389 errorCode = GetLastError();
390
391 theLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
392 NULL, /* message source */
393 errorCode, /* the message (error) ID */
394 0, /* default language environment */
395 (LPTSTR) theInfo, /* the buffer */
396 sizeof(theInfo), /* the buffer size */
397 NULL); /* no additional format args. */
398
399 /* Problem: could not get the error message. This should not happen if called correctly. */
400 if (theLength == 0) {
401 sprintf(errBuf, "DLL load failed with error code %d", errorCode);
402 } else {
403 int len;
404 /* For some reason a \r\n is appended to the text */
405 if (theLength >= 2 && theInfo[theLength-2] == '\r' && theInfo[theLength-1] == '\n') {
406 theLength -= 2;
407 theInfo[theLength] = '\0';
408 }
409 strcpy(errBuf, "DLL load failed: ");
410 len = strlen(errBuf);
411 strncpy(errBuf+len, theInfo, sizeof(errBuf)-len);
412 errBuf[sizeof(errBuf)-1] = '\0';
413 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000414 err_setstr(ImportError, errBuf);
415 return NULL;
416 }
417 p = GetProcAddress(hDLL, funcname);
418 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000419#endif /* MS_WIN32 */
420#ifdef MS_WIN16
Guido van Rossumdadc8241996-05-23 22:51:40 +0000421 {
422 HINSTANCE hDLL;
423 hDLL = LoadLibrary(pathname);
424 if (hDLL < HINSTANCE_ERROR){
425 char errBuf[256];
426 sprintf(errBuf, "DLL load failed with error code %d", hDLL);
427 err_setstr(ImportError, errBuf);
428 return NULL;
429 }
430 p = GetProcAddress(hDLL, funcname);
431 }
Guido van Rossum9b38a141996-09-11 23:12:24 +0000432#endif /* MS_WIN16 */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000433#ifdef USE_DL
434 p = dl_loadmod(getprogramname(), pathname, funcname);
435#endif /* USE_DL */
436#ifdef USE_RLD
437 {
438 NXStream *errorStream;
439 struct mach_header *new_header;
440 const char *filenames[2];
441 long ret;
442 unsigned long ptr;
443
444 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
445 filenames[0] = pathname;
446 filenames[1] = NULL;
447 ret = rld_load(errorStream, &new_header,
448 filenames, NULL);
449
450 /* extract the error messages for the exception */
451 if(!ret) {
452 char *streamBuf;
453 int len, maxLen;
454
455 NXPutc(errorStream, (char)0);
456
457 NXGetMemoryBuffer(errorStream,
458 &streamBuf, &len, &maxLen);
459 err_setstr(ImportError, streamBuf);
460 }
461
462 if(ret && rld_lookup(errorStream, funcname, &ptr))
463 p = (dl_funcptr) ptr;
464
465 NXCloseMemory(errorStream, NX_FREEBUFFER);
466
467 if(!ret)
468 return NULL;
469 }
470#endif /* USE_RLD */
471#ifdef hpux
472 {
473 shl_t lib;
474 int flags;
475
476 flags = BIND_DEFERRED;
477 if (verbose)
478 {
479 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
480 printf("shl_load %s\n",pathname);
481 }
482 lib = shl_load(pathname, flags, 0);
483 if (lib == NULL)
484 {
485 char buf[256];
486 if (verbose)
487 perror(pathname);
488 sprintf(buf, "Failed to load %.200s", pathname);
489 err_setstr(ImportError, buf);
490 return NULL;
491 }
492 if (verbose)
493 printf("shl_findsym %s\n", funcname);
494 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
495 if (p == NULL && verbose)
496 perror(funcname);
497 }
498#endif /* hpux */
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000499 got_it:
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000500 if (p == NULL) {
501 err_setstr(ImportError,
502 "dynamic module does not define init function");
503 return NULL;
504 }
505 (*p)();
506
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000507 m = dictlookup(import_modules, name);
508 if (m == NULL) {
509 if (err_occurred() == NULL)
510 err_setstr(SystemError,
511 "dynamic module not initialized properly");
512 return NULL;
513 }
Guido van Rossum1e612491996-08-19 22:12:10 +0000514 /* Remember the filename as the __file__ attribute */
515 d = getmoduledict(m);
516 s = newstringobject(pathname);
517 if (s == NULL || dictinsert(d, "__file__", s) != 0)
518 err_clear(); /* Not important enough to report */
519 XDECREF(s);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000520 if (verbose)
521 fprintf(stderr,
522 "import %s # dynamically loaded from %s\n",
523 name, pathname);
524 INCREF(m);
525 return m;
526#endif /* DYNAMIC_LINK */
527}
528
529
530#ifdef _AIX
531
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000532#include <ctype.h> /* for isdigit() */
533#include <errno.h> /* for global errno */
534#include <string.h> /* for strerror() */
535#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000536
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000537typedef struct Module {
538 struct Module *next;
539 void *entry;
540} Module, *ModulePtr;
541
542static int
543aix_getoldmodules(modlistptr)
544 void **modlistptr;
545{
546 register ModulePtr modptr, prevmodptr;
547 register struct ld_info *ldiptr;
548 register char *ldibuf;
549 register int errflag, bufsize = 1024;
550 register unsigned int offset;
551
552 /*
553 -- Get the list of loaded modules into ld_info structures.
554 */
555 if ((ldibuf = malloc(bufsize)) == NULL) {
556 err_setstr(ImportError, strerror(errno));
557 return -1;
558 }
559 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
560 && errno == ENOMEM) {
561 free(ldibuf);
562 bufsize += 1024;
563 if ((ldibuf = malloc(bufsize)) == NULL) {
564 err_setstr(ImportError, strerror(errno));
565 return -1;
566 }
567 }
568 if (errflag == -1) {
569 err_setstr(ImportError, strerror(errno));
570 return -1;
571 }
572 /*
573 -- Make the modules list from the ld_info structures.
574 */
575 ldiptr = (struct ld_info *)ldibuf;
576 prevmodptr = NULL;
577 do {
578 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
579 err_setstr(ImportError, strerror(errno));
580 while (*modlistptr) {
581 modptr = (ModulePtr)*modlistptr;
582 *modlistptr = (void *)modptr->next;
583 free(modptr);
584 }
585 return -1;
586 }
587 modptr->entry = ldiptr->ldinfo_dataorg;
588 modptr->next = NULL;
589 if (prevmodptr == NULL)
590 *modlistptr = (void *)modptr;
591 else
592 prevmodptr->next = modptr;
593 prevmodptr = modptr;
594 offset = (unsigned int)ldiptr->ldinfo_next;
595 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
596 } while (offset);
597 free(ldibuf);
598 return 0;
599}
600
601static int
602aix_bindnewmodule(newmoduleptr, modlistptr)
603 void *newmoduleptr;
604 void *modlistptr;
605{
606 register ModulePtr modptr;
607
608 /*
609 -- Bind the new module with the list of loaded modules.
610 */
611 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
612 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
613 return -1;
614 return 0;
615}
616
617static void
618aix_loaderror(pathname)
619 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000620{
621
Guido van Rossum236f62d1996-06-26 21:07:08 +0000622 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000623 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000624
625 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000626 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000627 char *errstr;
628 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000629 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000630 {L_ERROR_NOLIB, "can't load library:"},
631 {L_ERROR_UNDEF, "can't find symbol in library:"},
632 {L_ERROR_RLDBAD,
633 "RLD index out of range or bad relocation type:"},
634 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
635 {L_ERROR_MEMBER,
636 "file not an archive or does not contain requested member:"},
637 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000638 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000639 {L_ERROR_SYSTEM, "System error:"},
640 {L_ERROR_ERRNO, NULL}
641 };
642
643#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
644#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
645
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000646 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000647
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000648 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000649 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000650 ERRBUF_APPEND("\n");
651 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000652 for(i = 0; message[i] && *message[i]; i++) {
653 int nerr = atoi(message[i]);
654 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000655 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000656 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000657 }
658 while (isdigit(*message[i])) message[i]++ ;
659 ERRBUF_APPEND(message[i]);
660 ERRBUF_APPEND("\n");
661 }
662 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
663 err_setstr(ImportError, errbuf);
664 return;
665}
666
667#endif /* _AIX */