blob: 0d13a14e9d78d15fb4e5e71e1d584c4ffe2f857d [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
32extern int verbose; /* Defined in pythonrun.c */
33
34/* Explanation of some of the the various #defines used by dynamic linking...
35
36 symbol -- defined for:
37
38 DYNAMIC_LINK -- any kind of dynamic linking
Guido van Rossum46c76a61995-01-20 16:53:54 +000039 USE_RLD -- NeXT dynamic linking (currently disabled)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000040 USE_DL -- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
41 USE_SHLIB -- SunOS or IRIX 5 (SVR4?) shared libraries
42 _AIX -- AIX style dynamic linking
43 NT -- NT style dynamic linking (using DLLs)
44 _DL_FUNCPTR_DEFINED -- if the typedef dl_funcptr has been defined
Guido van Rossum6a75d261995-02-18 14:51:15 +000045 USE_MAC_SHARED_LIBRARY -- Mac CFM shared libraries
Guido van Rossum1ae940a1995-01-02 19:04:15 +000046 SHORT_EXT -- short extension for dynamic module, e.g. ".so"
47 LONG_EXT -- long extension, e.g. "module.so"
48 hpux -- HP-UX Dynamic Linking - defined by the compiler
Guido van Rossum46c76a61995-01-20 16:53:54 +000049 __NetBSD__ -- NetBSD shared libraries (not quite SVR4 compatible)
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
57#ifdef hpux
58#define DYNAMIC_LINK
59#include <errno.h>
60typedef void (*dl_funcptr)();
61#define _DL_FUNCPTR_DEFINED 1
62#define SHORT_EXT ".sl"
63#define LONG_EXT "module.sl"
64#endif
65
Guido van Rossum46c76a61995-01-20 16:53:54 +000066#ifdef __NetBSD__
67#define DYNAMIC_LINK
68#define USE_SHLIB
69
70#define dlerror() "error in dynamic linking"
71#endif
72
Guido van Rossum0fbec641995-02-27 10:15:36 +000073#ifdef __WIN32__
74#define NT
75#endif
76
Guido van Rossum1ae940a1995-01-02 19:04:15 +000077#ifdef NT
78#define DYNAMIC_LINK
79#include <windows.h>
80typedef FARPROC dl_funcptr;
81#define _DL_FUNCPTR_DEFINED
Guido van Rossum5fb1da71995-01-07 12:36:02 +000082#define SHORT_EXT ".pyd"
83#define LONG_EXT "module.pyd"
Guido van Rossum1ae940a1995-01-02 19:04:15 +000084#endif
85
Guido van Rossum46c76a61995-01-20 16:53:54 +000086#ifdef WITH_RLD
Guido van Rossum1ae940a1995-01-02 19:04:15 +000087#define DYNAMIC_LINK
88#define USE_RLD
89#endif
90
91#ifdef WITH_SGI_DL
92#define DYNAMIC_LINK
93#define USE_DL
94#endif
95
96#ifdef WITH_DL_DLD
97#define DYNAMIC_LINK
98#define USE_DL
99#endif
100
Guido van Rossum6a75d261995-02-18 14:51:15 +0000101#ifdef __CFM68K__
102#define USE_MAC_SHARED_LIBRARY
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000103#endif
104
Jack Jansen4e043731995-02-13 22:42:34 +0000105#ifdef USE_MAC_SHARED_LIBRARY
106#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000107#define SHORT_EXT ".slb"
108#define LONG_EXT "module.slb"
Jack Jansen4e043731995-02-13 22:42:34 +0000109#ifndef _DL_FUNCPTR_DEFINED
110typedef void (*dl_funcptr)();
111#endif
112#endif
113
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000114#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
115#define DYNAMIC_LINK
116#define USE_SHLIB
117#endif
118
119#ifdef _AIX
120#define DYNAMIC_LINK
121#include <sys/ldr.h>
122typedef void (*dl_funcptr)();
123#define _DL_FUNCPTR_DEFINED
124static void aix_loaderror(char *name);
125#endif
126
127#ifdef DYNAMIC_LINK
128
129#ifdef USE_SHLIB
Guido van Rossum46c76a61995-01-20 16:53:54 +0000130#ifdef __NetBSD__
131#include <nlist.h>
132#include <link.h>
133#else
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000134#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000135#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000136#ifndef _DL_FUNCPTR_DEFINED
137typedef void (*dl_funcptr)();
138#endif
139#ifndef RTLD_LAZY
140#define RTLD_LAZY 1
141#endif
142#define SHORT_EXT ".so"
143#define LONG_EXT "module.so"
144#endif /* USE_SHLIB */
145
146#if defined(USE_DL) || defined(hpux)
147#include "dl.h"
148#endif
149
Jack Jansen4e043731995-02-13 22:42:34 +0000150#ifdef USE_MAC_SHARED_LIBRARY
151#include <CodeFragments.h>
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000152#ifdef __CFM68K__ /* Really just an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000153#define CFragConnectionID ConnectionID
154#define kLoadCFrag 0x01
155#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000156#include <Files.h>
157#include "macdefs.h"
158#include "macglue.h"
159#endif
160
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000161#ifdef USE_RLD
162#include <mach-o/rld.h>
163#define FUNCNAME_PATTERN "_init%.200s"
164#ifndef _DL_FUNCPTR_DEFINED
165typedef void (*dl_funcptr)();
166#endif
167#endif /* USE_RLD */
168
169extern char *getprogramname();
170
171#ifndef FUNCNAME_PATTERN
Guido van Rossum0fbec641995-02-27 10:15:36 +0000172#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000173#define FUNCNAME_PATTERN "_init%.200s"
174#else
175#define FUNCNAME_PATTERN "init%.200s"
176#endif
177#endif
178
179#if !defined(SHORT_EXT) && !defined(LONG_EXT)
180#define SHORT_EXT ".o"
181#define LONG_EXT "module.o"
182#endif /* !SHORT_EXT && !LONG_EXT */
183
184#endif /* DYNAMIC_LINK */
185
Guido van Rossum6a75d261995-02-18 14:51:15 +0000186/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000187#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000188#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000189#endif
190
191/* Pass it on to import.c */
192int import_maxsuffixsize = MAXSUFFIXSIZE;
193
194struct filedescr import_filetab[] = {
195#ifdef SHORT_EXT
196 {SHORT_EXT, "rb", C_EXTENSION},
197#endif /* !SHORT_EXT */
198#ifdef LONG_EXT
199 {LONG_EXT, "rb", C_EXTENSION},
200#endif /* !LONG_EXT */
201 {".py", "r", PY_SOURCE},
202 {".pyc", "rb", PY_COMPILED},
203 {0, 0}
204};
205
206object *
207load_dynamic_module(name, pathname)
208 char *name;
209 char *pathname;
210{
211#ifndef DYNAMIC_LINK
212 err_setstr(ImportError, "dynamically linked modules not supported");
213 return NULL;
214#else
215 object *m;
216 char funcname[258];
217 dl_funcptr p = NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000218 sprintf(funcname, FUNCNAME_PATTERN, name);
Jack Jansen4e043731995-02-13 22:42:34 +0000219#ifdef USE_MAC_SHARED_LIBRARY
Guido van Rossum6a75d261995-02-18 14:51:15 +0000220 /* Dynamic loading of CFM shared libraries on the Mac */
Jack Jansen4e043731995-02-13 22:42:34 +0000221 {
222 FSSpec libspec;
223 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000224 Ptr mainAddr;
225 Str255 errMessage;
226 OSErr err;
Jack Jansen4e043731995-02-13 22:42:34 +0000227
228 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Guido van Rossum6a75d261995-02-18 14:51:15 +0000229 err = GetDiskFragment(&libspec, 0, 0, Pstring(name),
230 kLoadCFrag, &connID, &mainAddr,
231 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000232 if ( err ) {
233 char buf[512];
234
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000235 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000236 err_setstr(ImportError, buf);
237 return NULL;
238 }
239 p = (dl_funcptr)mainAddr;
240 }
241#endif /* USE_MAC_SHARED_LIBRARY */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000242#ifdef USE_SHLIB
243 {
244#ifdef RTLD_NOW
245 /* RTLD_NOW: resolve externals now
246 (i.e. core dump now if some are missing) */
247 void *handle = dlopen(pathname, RTLD_NOW);
248#else
249 void *handle;
250 if (verbose)
251 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
252 handle = dlopen(pathname, RTLD_LAZY);
253#endif /* RTLD_NOW */
254 if (handle == NULL) {
255 err_setstr(ImportError, dlerror());
256 return NULL;
257 }
258 p = (dl_funcptr) dlsym(handle, funcname);
259 }
260#endif /* USE_SHLIB */
261#ifdef _AIX
262 p = (dl_funcptr) load(pathname, 1, 0);
263 if (p == NULL) {
264 aix_loaderror(pathname);
265 return NULL;
266 }
267#endif /* _AIX */
268#ifdef NT
269 {
270 HINSTANCE hDLL;
271 hDLL = LoadLibrary(pathname);
272 if (hDLL==NULL){
273 char errBuf[64];
274 sprintf(errBuf, "DLL load failed with error code %d",
275 GetLastError());
276 err_setstr(ImportError, errBuf);
277 return NULL;
278 }
279 p = GetProcAddress(hDLL, funcname);
280 }
281#endif /* NT */
282#ifdef USE_DL
283 p = dl_loadmod(getprogramname(), pathname, funcname);
284#endif /* USE_DL */
285#ifdef USE_RLD
286 {
287 NXStream *errorStream;
288 struct mach_header *new_header;
289 const char *filenames[2];
290 long ret;
291 unsigned long ptr;
292
293 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
294 filenames[0] = pathname;
295 filenames[1] = NULL;
296 ret = rld_load(errorStream, &new_header,
297 filenames, NULL);
298
299 /* extract the error messages for the exception */
300 if(!ret) {
301 char *streamBuf;
302 int len, maxLen;
303
304 NXPutc(errorStream, (char)0);
305
306 NXGetMemoryBuffer(errorStream,
307 &streamBuf, &len, &maxLen);
308 err_setstr(ImportError, streamBuf);
309 }
310
311 if(ret && rld_lookup(errorStream, funcname, &ptr))
312 p = (dl_funcptr) ptr;
313
314 NXCloseMemory(errorStream, NX_FREEBUFFER);
315
316 if(!ret)
317 return NULL;
318 }
319#endif /* USE_RLD */
320#ifdef hpux
321 {
322 shl_t lib;
323 int flags;
324
325 flags = BIND_DEFERRED;
326 if (verbose)
327 {
328 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
329 printf("shl_load %s\n",pathname);
330 }
331 lib = shl_load(pathname, flags, 0);
332 if (lib == NULL)
333 {
334 char buf[256];
335 if (verbose)
336 perror(pathname);
337 sprintf(buf, "Failed to load %.200s", pathname);
338 err_setstr(ImportError, buf);
339 return NULL;
340 }
341 if (verbose)
342 printf("shl_findsym %s\n", funcname);
343 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
344 if (p == NULL && verbose)
345 perror(funcname);
346 }
347#endif /* hpux */
348 if (p == NULL) {
349 err_setstr(ImportError,
350 "dynamic module does not define init function");
351 return NULL;
352 }
353 (*p)();
354
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000355 m = dictlookup(import_modules, name);
356 if (m == NULL) {
357 if (err_occurred() == NULL)
358 err_setstr(SystemError,
359 "dynamic module not initialized properly");
360 return NULL;
361 }
362 if (verbose)
363 fprintf(stderr,
364 "import %s # dynamically loaded from %s\n",
365 name, pathname);
366 INCREF(m);
367 return m;
368#endif /* DYNAMIC_LINK */
369}
370
371
372#ifdef _AIX
373
374#include <ctype.h> /* for isdigit() */
375#include <errno.h> /* for global errno */
376#include <string.h> /* for strerror() */
377
378void aix_loaderror(char *pathname)
379{
380
381 char *message[8], errbuf[1024];
382 int i,j;
383
384 struct errtab {
385 int errno;
386 char *errstr;
387 } load_errtab[] = {
388 {L_ERROR_TOOMANY, "to many errors, rest skipped."},
389 {L_ERROR_NOLIB, "can't load library:"},
390 {L_ERROR_UNDEF, "can't find symbol in library:"},
391 {L_ERROR_RLDBAD,
392 "RLD index out of range or bad relocation type:"},
393 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
394 {L_ERROR_MEMBER,
395 "file not an archive or does not contain requested member:"},
396 {L_ERROR_TYPE, "symbol table mismatch:"},
397 {L_ERROR_ALIGN, "text allignment in file is wrong."},
398 {L_ERROR_SYSTEM, "System error:"},
399 {L_ERROR_ERRNO, NULL}
400 };
401
402#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
403#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
404
405 sprintf(errbuf, " from module %.200s ", pathname);
406
407 if (!loadquery(1, &message[0], sizeof(message)))
408 ERRBUF_APPEND(strerror(errno));
409 for(i = 0; message[i] && *message[i]; i++) {
410 int nerr = atoi(message[i]);
411 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
412 if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
413 ERRBUF_APPEND(load_errtab[i].errstr);
414 }
415 while (isdigit(*message[i])) message[i]++ ;
416 ERRBUF_APPEND(message[i]);
417 ERRBUF_APPEND("\n");
418 }
419 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
420 err_setstr(ImportError, errbuf);
421 return;
422}
423
424#endif /* _AIX */