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