blob: 00a033e92c51ee5b3e520f5608f8aa49d56484ee [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
45 WITH_MAC_DL -- Mac dynamic linking (highly experimental)
46 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
97#ifdef WITH_MAC_DL
98#define DYNAMIC_LINK
99#endif
100
101#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
102#define DYNAMIC_LINK
103#define USE_SHLIB
104#endif
105
106#ifdef _AIX
107#define DYNAMIC_LINK
108#include <sys/ldr.h>
109typedef void (*dl_funcptr)();
110#define _DL_FUNCPTR_DEFINED
111static void aix_loaderror(char *name);
112#endif
113
114#ifdef DYNAMIC_LINK
115
116#ifdef USE_SHLIB
Guido van Rossum46c76a61995-01-20 16:53:54 +0000117#ifdef __NetBSD__
118#include <nlist.h>
119#include <link.h>
120#else
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000121#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000122#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000123#ifndef _DL_FUNCPTR_DEFINED
124typedef void (*dl_funcptr)();
125#endif
126#ifndef RTLD_LAZY
127#define RTLD_LAZY 1
128#endif
129#define SHORT_EXT ".so"
130#define LONG_EXT "module.so"
131#endif /* USE_SHLIB */
132
133#if defined(USE_DL) || defined(hpux)
134#include "dl.h"
135#endif
136
137#ifdef WITH_MAC_DL
138#include "dynamic_load.h"
139#endif
140
141#ifdef USE_RLD
142#include <mach-o/rld.h>
143#define FUNCNAME_PATTERN "_init%.200s"
144#ifndef _DL_FUNCPTR_DEFINED
145typedef void (*dl_funcptr)();
146#endif
147#endif /* USE_RLD */
148
149extern char *getprogramname();
150
151#ifndef FUNCNAME_PATTERN
Guido van Rossum46c76a61995-01-20 16:53:54 +0000152#if defined(__hp9000s300) || defined(__NetBSD__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000153#define FUNCNAME_PATTERN "_init%.200s"
154#else
155#define FUNCNAME_PATTERN "init%.200s"
156#endif
157#endif
158
159#if !defined(SHORT_EXT) && !defined(LONG_EXT)
160#define SHORT_EXT ".o"
161#define LONG_EXT "module.o"
162#endif /* !SHORT_EXT && !LONG_EXT */
163
164#endif /* DYNAMIC_LINK */
165
166/* Max length of module suffix searched for -- accommodates "module.so" */
167#ifndef MAXSUFFIXSIZE
168#define MAXSUFFIXSIZE 10
169#endif
170
171/* Pass it on to import.c */
172int import_maxsuffixsize = MAXSUFFIXSIZE;
173
174struct filedescr import_filetab[] = {
175#ifdef SHORT_EXT
176 {SHORT_EXT, "rb", C_EXTENSION},
177#endif /* !SHORT_EXT */
178#ifdef LONG_EXT
179 {LONG_EXT, "rb", C_EXTENSION},
180#endif /* !LONG_EXT */
181 {".py", "r", PY_SOURCE},
182 {".pyc", "rb", PY_COMPILED},
183 {0, 0}
184};
185
186object *
187load_dynamic_module(name, pathname)
188 char *name;
189 char *pathname;
190{
191#ifndef DYNAMIC_LINK
192 err_setstr(ImportError, "dynamically linked modules not supported");
193 return NULL;
194#else
195 object *m;
196 char funcname[258];
197 dl_funcptr p = NULL;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000198 sprintf(funcname, FUNCNAME_PATTERN, name);
199#ifdef WITH_MAC_DL
200 {
201 object *v = dynamic_load(pathname);
202 if (v == NULL)
203 return NULL;
204 }
205#else /* !WITH_MAC_DL */
206#ifdef USE_SHLIB
207 {
208#ifdef RTLD_NOW
209 /* RTLD_NOW: resolve externals now
210 (i.e. core dump now if some are missing) */
211 void *handle = dlopen(pathname, RTLD_NOW);
212#else
213 void *handle;
214 if (verbose)
215 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
216 handle = dlopen(pathname, RTLD_LAZY);
217#endif /* RTLD_NOW */
218 if (handle == NULL) {
219 err_setstr(ImportError, dlerror());
220 return NULL;
221 }
222 p = (dl_funcptr) dlsym(handle, funcname);
223 }
224#endif /* USE_SHLIB */
225#ifdef _AIX
226 p = (dl_funcptr) load(pathname, 1, 0);
227 if (p == NULL) {
228 aix_loaderror(pathname);
229 return NULL;
230 }
231#endif /* _AIX */
232#ifdef NT
233 {
234 HINSTANCE hDLL;
235 hDLL = LoadLibrary(pathname);
236 if (hDLL==NULL){
237 char errBuf[64];
238 sprintf(errBuf, "DLL load failed with error code %d",
239 GetLastError());
240 err_setstr(ImportError, errBuf);
241 return NULL;
242 }
243 p = GetProcAddress(hDLL, funcname);
244 }
245#endif /* NT */
246#ifdef USE_DL
247 p = dl_loadmod(getprogramname(), pathname, funcname);
248#endif /* USE_DL */
249#ifdef USE_RLD
250 {
251 NXStream *errorStream;
252 struct mach_header *new_header;
253 const char *filenames[2];
254 long ret;
255 unsigned long ptr;
256
257 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
258 filenames[0] = pathname;
259 filenames[1] = NULL;
260 ret = rld_load(errorStream, &new_header,
261 filenames, NULL);
262
263 /* extract the error messages for the exception */
264 if(!ret) {
265 char *streamBuf;
266 int len, maxLen;
267
268 NXPutc(errorStream, (char)0);
269
270 NXGetMemoryBuffer(errorStream,
271 &streamBuf, &len, &maxLen);
272 err_setstr(ImportError, streamBuf);
273 }
274
275 if(ret && rld_lookup(errorStream, funcname, &ptr))
276 p = (dl_funcptr) ptr;
277
278 NXCloseMemory(errorStream, NX_FREEBUFFER);
279
280 if(!ret)
281 return NULL;
282 }
283#endif /* USE_RLD */
284#ifdef hpux
285 {
286 shl_t lib;
287 int flags;
288
289 flags = BIND_DEFERRED;
290 if (verbose)
291 {
292 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
293 printf("shl_load %s\n",pathname);
294 }
295 lib = shl_load(pathname, flags, 0);
296 if (lib == NULL)
297 {
298 char buf[256];
299 if (verbose)
300 perror(pathname);
301 sprintf(buf, "Failed to load %.200s", pathname);
302 err_setstr(ImportError, buf);
303 return NULL;
304 }
305 if (verbose)
306 printf("shl_findsym %s\n", funcname);
307 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
308 if (p == NULL && verbose)
309 perror(funcname);
310 }
311#endif /* hpux */
312 if (p == NULL) {
313 err_setstr(ImportError,
314 "dynamic module does not define init function");
315 return NULL;
316 }
317 (*p)();
318
319#endif /* !WITH_MAC_DL */
320 m = dictlookup(import_modules, name);
321 if (m == NULL) {
322 if (err_occurred() == NULL)
323 err_setstr(SystemError,
324 "dynamic module not initialized properly");
325 return NULL;
326 }
327 if (verbose)
328 fprintf(stderr,
329 "import %s # dynamically loaded from %s\n",
330 name, pathname);
331 INCREF(m);
332 return m;
333#endif /* DYNAMIC_LINK */
334}
335
336
337#ifdef _AIX
338
339#include <ctype.h> /* for isdigit() */
340#include <errno.h> /* for global errno */
341#include <string.h> /* for strerror() */
342
343void aix_loaderror(char *pathname)
344{
345
346 char *message[8], errbuf[1024];
347 int i,j;
348
349 struct errtab {
350 int errno;
351 char *errstr;
352 } load_errtab[] = {
353 {L_ERROR_TOOMANY, "to many errors, rest skipped."},
354 {L_ERROR_NOLIB, "can't load library:"},
355 {L_ERROR_UNDEF, "can't find symbol in library:"},
356 {L_ERROR_RLDBAD,
357 "RLD index out of range or bad relocation type:"},
358 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
359 {L_ERROR_MEMBER,
360 "file not an archive or does not contain requested member:"},
361 {L_ERROR_TYPE, "symbol table mismatch:"},
362 {L_ERROR_ALIGN, "text allignment in file is wrong."},
363 {L_ERROR_SYSTEM, "System error:"},
364 {L_ERROR_ERRNO, NULL}
365 };
366
367#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
368#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
369
370 sprintf(errbuf, " from module %.200s ", pathname);
371
372 if (!loadquery(1, &message[0], sizeof(message)))
373 ERRBUF_APPEND(strerror(errno));
374 for(i = 0; message[i] && *message[i]; i++) {
375 int nerr = atoi(message[i]);
376 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
377 if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
378 ERRBUF_APPEND(load_errtab[i].errstr);
379 }
380 while (isdigit(*message[i])) message[i]++ ;
381 ERRBUF_APPEND(message[i]);
382 ERRBUF_APPEND("\n");
383 }
384 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
385 err_setstr(ImportError, errbuf);
386 return;
387}
388
389#endif /* _AIX */