blob: 5c6b208c8fdb88905b12ef570f0c3cea5a6df6f6 [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 Rossum1ae940a1995-01-02 19:04:15 +000073#ifdef NT
74#define DYNAMIC_LINK
75#include <windows.h>
76typedef FARPROC dl_funcptr;
77#define _DL_FUNCPTR_DEFINED
Guido van Rossum5fb1da71995-01-07 12:36:02 +000078#define SHORT_EXT ".pyd"
79#define LONG_EXT "module.pyd"
Guido van Rossum1ae940a1995-01-02 19:04:15 +000080#endif
81
Guido van Rossum46c76a61995-01-20 16:53:54 +000082#ifdef WITH_RLD
Guido van Rossum1ae940a1995-01-02 19:04:15 +000083#define DYNAMIC_LINK
84#define USE_RLD
85#endif
86
87#ifdef WITH_SGI_DL
88#define DYNAMIC_LINK
89#define USE_DL
90#endif
91
92#ifdef WITH_DL_DLD
93#define DYNAMIC_LINK
94#define USE_DL
95#endif
96
Guido van Rossum6a75d261995-02-18 14:51:15 +000097#ifdef __CFM68K__
98#define USE_MAC_SHARED_LIBRARY
Guido van Rossum1ae940a1995-01-02 19:04:15 +000099#endif
100
Jack Jansen4e043731995-02-13 22:42:34 +0000101#ifdef USE_MAC_SHARED_LIBRARY
102#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000103#define SHORT_EXT ".slb"
104#define LONG_EXT "module.slb"
Jack Jansen4e043731995-02-13 22:42:34 +0000105#ifndef _DL_FUNCPTR_DEFINED
106typedef void (*dl_funcptr)();
107#endif
108#endif
109
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000110#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
111#define DYNAMIC_LINK
112#define USE_SHLIB
113#endif
114
115#ifdef _AIX
116#define DYNAMIC_LINK
117#include <sys/ldr.h>
118typedef void (*dl_funcptr)();
119#define _DL_FUNCPTR_DEFINED
120static void aix_loaderror(char *name);
121#endif
122
123#ifdef DYNAMIC_LINK
124
125#ifdef USE_SHLIB
Guido van Rossum46c76a61995-01-20 16:53:54 +0000126#ifdef __NetBSD__
127#include <nlist.h>
128#include <link.h>
129#else
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000130#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000131#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000132#ifndef _DL_FUNCPTR_DEFINED
133typedef void (*dl_funcptr)();
134#endif
135#ifndef RTLD_LAZY
136#define RTLD_LAZY 1
137#endif
138#define SHORT_EXT ".so"
139#define LONG_EXT "module.so"
140#endif /* USE_SHLIB */
141
142#if defined(USE_DL) || defined(hpux)
143#include "dl.h"
144#endif
145
Jack Jansen4e043731995-02-13 22:42:34 +0000146#ifdef USE_MAC_SHARED_LIBRARY
147#include <CodeFragments.h>
Guido van Rossum6a75d261995-02-18 14:51:15 +0000148#ifdef __SC__ /* Really just an older version of Universal Headers */
149#define CFragConnectionID ConnectionID
150#define kLoadCFrag 0x01
151#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000152#include <Files.h>
153#include "macdefs.h"
154#include "macglue.h"
155#endif
156
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000157#ifdef USE_RLD
158#include <mach-o/rld.h>
159#define FUNCNAME_PATTERN "_init%.200s"
160#ifndef _DL_FUNCPTR_DEFINED
161typedef void (*dl_funcptr)();
162#endif
163#endif /* USE_RLD */
164
165extern char *getprogramname();
166
167#ifndef FUNCNAME_PATTERN
Guido van Rossum46c76a61995-01-20 16:53:54 +0000168#if defined(__hp9000s300) || defined(__NetBSD__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000169#define FUNCNAME_PATTERN "_init%.200s"
170#else
171#define FUNCNAME_PATTERN "init%.200s"
172#endif
173#endif
174
175#if !defined(SHORT_EXT) && !defined(LONG_EXT)
176#define SHORT_EXT ".o"
177#define LONG_EXT "module.o"
178#endif /* !SHORT_EXT && !LONG_EXT */
179
180#endif /* DYNAMIC_LINK */
181
Guido van Rossum6a75d261995-02-18 14:51:15 +0000182/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000183#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000184#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000185#endif
186
187/* Pass it on to import.c */
188int import_maxsuffixsize = MAXSUFFIXSIZE;
189
190struct filedescr import_filetab[] = {
191#ifdef SHORT_EXT
192 {SHORT_EXT, "rb", C_EXTENSION},
193#endif /* !SHORT_EXT */
194#ifdef LONG_EXT
195 {LONG_EXT, "rb", C_EXTENSION},
196#endif /* !LONG_EXT */
197 {".py", "r", PY_SOURCE},
198 {".pyc", "rb", PY_COMPILED},
199 {0, 0}
200};
201
202object *
203load_dynamic_module(name, pathname)
204 char *name;
205 char *pathname;
206{
207#ifndef DYNAMIC_LINK
208 err_setstr(ImportError, "dynamically linked modules not supported");
209 return NULL;
210#else
211 object *m;
212 char funcname[258];
213 dl_funcptr p = NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000214 sprintf(funcname, FUNCNAME_PATTERN, name);
Jack Jansen4e043731995-02-13 22:42:34 +0000215#ifdef USE_MAC_SHARED_LIBRARY
Guido van Rossum6a75d261995-02-18 14:51:15 +0000216 /* Dynamic loading of CFM shared libraries on the Mac */
Jack Jansen4e043731995-02-13 22:42:34 +0000217 {
218 FSSpec libspec;
219 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000220 Ptr mainAddr;
221 Str255 errMessage;
222 OSErr err;
Jack Jansen4e043731995-02-13 22:42:34 +0000223
224 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Guido van Rossum6a75d261995-02-18 14:51:15 +0000225 err = GetDiskFragment(&libspec, 0, 0, Pstring(name),
226 kLoadCFrag, &connID, &mainAddr,
227 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000228 if ( err ) {
229 char buf[512];
230
Guido van Rossum6a75d261995-02-18 14:51:15 +0000231 sprintf(buf, "%#s: %s", errMessage, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000232 err_setstr(ImportError, buf);
233 return NULL;
234 }
235 p = (dl_funcptr)mainAddr;
236 }
237#endif /* USE_MAC_SHARED_LIBRARY */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000238#ifdef USE_SHLIB
239 {
240#ifdef RTLD_NOW
241 /* RTLD_NOW: resolve externals now
242 (i.e. core dump now if some are missing) */
243 void *handle = dlopen(pathname, RTLD_NOW);
244#else
245 void *handle;
246 if (verbose)
247 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
248 handle = dlopen(pathname, RTLD_LAZY);
249#endif /* RTLD_NOW */
250 if (handle == NULL) {
251 err_setstr(ImportError, dlerror());
252 return NULL;
253 }
254 p = (dl_funcptr) dlsym(handle, funcname);
255 }
256#endif /* USE_SHLIB */
257#ifdef _AIX
258 p = (dl_funcptr) load(pathname, 1, 0);
259 if (p == NULL) {
260 aix_loaderror(pathname);
261 return NULL;
262 }
263#endif /* _AIX */
264#ifdef NT
265 {
266 HINSTANCE hDLL;
267 hDLL = LoadLibrary(pathname);
268 if (hDLL==NULL){
269 char errBuf[64];
270 sprintf(errBuf, "DLL load failed with error code %d",
271 GetLastError());
272 err_setstr(ImportError, errBuf);
273 return NULL;
274 }
275 p = GetProcAddress(hDLL, funcname);
276 }
277#endif /* NT */
278#ifdef USE_DL
279 p = dl_loadmod(getprogramname(), pathname, funcname);
280#endif /* USE_DL */
281#ifdef USE_RLD
282 {
283 NXStream *errorStream;
284 struct mach_header *new_header;
285 const char *filenames[2];
286 long ret;
287 unsigned long ptr;
288
289 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
290 filenames[0] = pathname;
291 filenames[1] = NULL;
292 ret = rld_load(errorStream, &new_header,
293 filenames, NULL);
294
295 /* extract the error messages for the exception */
296 if(!ret) {
297 char *streamBuf;
298 int len, maxLen;
299
300 NXPutc(errorStream, (char)0);
301
302 NXGetMemoryBuffer(errorStream,
303 &streamBuf, &len, &maxLen);
304 err_setstr(ImportError, streamBuf);
305 }
306
307 if(ret && rld_lookup(errorStream, funcname, &ptr))
308 p = (dl_funcptr) ptr;
309
310 NXCloseMemory(errorStream, NX_FREEBUFFER);
311
312 if(!ret)
313 return NULL;
314 }
315#endif /* USE_RLD */
316#ifdef hpux
317 {
318 shl_t lib;
319 int flags;
320
321 flags = BIND_DEFERRED;
322 if (verbose)
323 {
324 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
325 printf("shl_load %s\n",pathname);
326 }
327 lib = shl_load(pathname, flags, 0);
328 if (lib == NULL)
329 {
330 char buf[256];
331 if (verbose)
332 perror(pathname);
333 sprintf(buf, "Failed to load %.200s", pathname);
334 err_setstr(ImportError, buf);
335 return NULL;
336 }
337 if (verbose)
338 printf("shl_findsym %s\n", funcname);
339 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
340 if (p == NULL && verbose)
341 perror(funcname);
342 }
343#endif /* hpux */
344 if (p == NULL) {
345 err_setstr(ImportError,
346 "dynamic module does not define init function");
347 return NULL;
348 }
349 (*p)();
350
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000351 m = dictlookup(import_modules, name);
352 if (m == NULL) {
353 if (err_occurred() == NULL)
354 err_setstr(SystemError,
355 "dynamic module not initialized properly");
356 return NULL;
357 }
358 if (verbose)
359 fprintf(stderr,
360 "import %s # dynamically loaded from %s\n",
361 name, pathname);
362 INCREF(m);
363 return m;
364#endif /* DYNAMIC_LINK */
365}
366
367
368#ifdef _AIX
369
370#include <ctype.h> /* for isdigit() */
371#include <errno.h> /* for global errno */
372#include <string.h> /* for strerror() */
373
374void aix_loaderror(char *pathname)
375{
376
377 char *message[8], errbuf[1024];
378 int i,j;
379
380 struct errtab {
381 int errno;
382 char *errstr;
383 } load_errtab[] = {
384 {L_ERROR_TOOMANY, "to many errors, rest skipped."},
385 {L_ERROR_NOLIB, "can't load library:"},
386 {L_ERROR_UNDEF, "can't find symbol in library:"},
387 {L_ERROR_RLDBAD,
388 "RLD index out of range or bad relocation type:"},
389 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
390 {L_ERROR_MEMBER,
391 "file not an archive or does not contain requested member:"},
392 {L_ERROR_TYPE, "symbol table mismatch:"},
393 {L_ERROR_ALIGN, "text allignment in file is wrong."},
394 {L_ERROR_SYSTEM, "System error:"},
395 {L_ERROR_ERRNO, NULL}
396 };
397
398#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
399#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
400
401 sprintf(errbuf, " from module %.200s ", pathname);
402
403 if (!loadquery(1, &message[0], sizeof(message)))
404 ERRBUF_APPEND(strerror(errno));
405 for(i = 0; message[i] && *message[i]; i++) {
406 int nerr = atoi(message[i]);
407 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
408 if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
409 ERRBUF_APPEND(load_errtab[i].errstr);
410 }
411 while (isdigit(*message[i])) message[i]++ ;
412 ERRBUF_APPEND(message[i]);
413 ERRBUF_APPEND("\n");
414 }
415 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
416 err_setstr(ImportError, errbuf);
417 return;
418}
419
420#endif /* _AIX */