blob: d68b00282b35488eebb2439d8e28a1e8e001d1b1 [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
41 NT -- NT style dynamic linking (using DLLs)
Guido van Rossumdadc8241996-05-23 22:51:40 +000042 WIN16_DL -- 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
58#define hpux
59#endif
60
Guido van Rossum1ae940a1995-01-02 19:04:15 +000061#ifdef hpux
62#define DYNAMIC_LINK
63#include <errno.h>
64typedef void (*dl_funcptr)();
65#define _DL_FUNCPTR_DEFINED 1
66#define SHORT_EXT ".sl"
67#define LONG_EXT "module.sl"
68#endif
69
Guido van Rossum25e85291996-02-25 05:02:29 +000070#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +000071#define DYNAMIC_LINK
72#define USE_SHLIB
73
74#define dlerror() "error in dynamic linking"
75#endif
76
Guido van Rossum0fbec641995-02-27 10:15:36 +000077#ifdef __WIN32__
78#define NT
79#endif
80
Guido van Rossumdadc8241996-05-23 22:51:40 +000081#ifdef MS_WIN16
82#define WIN16_DL
83#endif
84
85#if defined(NT) || defined(WIN16_DL)
Guido van Rossum1ae940a1995-01-02 19:04:15 +000086#define DYNAMIC_LINK
87#include <windows.h>
88typedef FARPROC dl_funcptr;
89#define _DL_FUNCPTR_DEFINED
Guido van Rossum5fb1da71995-01-07 12:36:02 +000090#define SHORT_EXT ".pyd"
Guido van Rossume71a9471996-04-09 02:39:15 +000091#define LONG_EXT ".dll"
Guido van Rossum1ae940a1995-01-02 19:04:15 +000092#endif
93
Guido van Rossum75f288d1995-06-14 22:07:26 +000094#ifdef NeXT
Guido van Rossum1ae940a1995-01-02 19:04:15 +000095#define DYNAMIC_LINK
96#define USE_RLD
97#endif
98
99#ifdef WITH_SGI_DL
100#define DYNAMIC_LINK
101#define USE_DL
102#endif
103
104#ifdef WITH_DL_DLD
105#define DYNAMIC_LINK
106#define USE_DL
107#endif
108
Guido van Rossum6a75d261995-02-18 14:51:15 +0000109#ifdef __CFM68K__
Jack Jansen5d9acb61995-06-14 14:54:25 +0000110#define USE_MAC_DYNAMIC_LOADING
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000111#endif
112
Jack Jansen5d9acb61995-06-14 14:54:25 +0000113#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen4e043731995-02-13 22:42:34 +0000114#define DYNAMIC_LINK
Guido van Rossum6a75d261995-02-18 14:51:15 +0000115#define SHORT_EXT ".slb"
116#define LONG_EXT "module.slb"
Jack Jansen4e043731995-02-13 22:42:34 +0000117#ifndef _DL_FUNCPTR_DEFINED
118typedef void (*dl_funcptr)();
119#endif
120#endif
121
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000122#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
123#define DYNAMIC_LINK
124#define USE_SHLIB
125#endif
126
127#ifdef _AIX
128#define DYNAMIC_LINK
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000129#define SHORT_EXT ".so"
130#define LONG_EXT "module.so"
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000131#include <sys/ldr.h>
132typedef void (*dl_funcptr)();
133#define _DL_FUNCPTR_DEFINED
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000134static int aix_getoldmodules(void **);
135static int aix_bindnewmodule(void *, void *);
136static void aix_loaderror(char *);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000137#endif
138
139#ifdef DYNAMIC_LINK
140
141#ifdef USE_SHLIB
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000142#include <sys/types.h>
143#include <sys/stat.h>
Guido van Rossum25e85291996-02-25 05:02:29 +0000144#if defined(__NetBSD__) || defined(__FreeBSD__)
Guido van Rossum46c76a61995-01-20 16:53:54 +0000145#include <nlist.h>
146#include <link.h>
147#else
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000148#include <dlfcn.h>
Guido van Rossum46c76a61995-01-20 16:53:54 +0000149#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000150#ifndef _DL_FUNCPTR_DEFINED
151typedef void (*dl_funcptr)();
152#endif
153#ifndef RTLD_LAZY
154#define RTLD_LAZY 1
155#endif
156#define SHORT_EXT ".so"
157#define LONG_EXT "module.so"
158#endif /* USE_SHLIB */
159
160#if defined(USE_DL) || defined(hpux)
161#include "dl.h"
162#endif
163
Jack Jansen5d9acb61995-06-14 14:54:25 +0000164#ifdef USE_MAC_DYNAMIC_LOADING
Jack Jansen0a72e8d1995-10-23 13:54:01 +0000165#include <Aliases.h>
Jack Jansen4e043731995-02-13 22:42:34 +0000166#include <CodeFragments.h>
Jack Janseneceb3e31995-06-27 13:15:15 +0000167#ifdef SYMANTEC__CFM68K__ /* Really just an older version of Universal Headers */
Guido van Rossum6a75d261995-02-18 14:51:15 +0000168#define CFragConnectionID ConnectionID
169#define kLoadCFrag 0x01
170#endif
Jack Jansen4e043731995-02-13 22:42:34 +0000171#include <Files.h>
172#include "macdefs.h"
173#include "macglue.h"
174#endif
175
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000176#ifdef USE_RLD
177#include <mach-o/rld.h>
178#define FUNCNAME_PATTERN "_init%.200s"
179#ifndef _DL_FUNCPTR_DEFINED
180typedef void (*dl_funcptr)();
181#endif
182#endif /* USE_RLD */
183
184extern char *getprogramname();
185
186#ifndef FUNCNAME_PATTERN
Guido van Rossum25e85291996-02-25 05:02:29 +0000187#if defined(__hp9000s300) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__BORLANDC__)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000188#define FUNCNAME_PATTERN "_init%.200s"
189#else
190#define FUNCNAME_PATTERN "init%.200s"
191#endif
192#endif
193
194#if !defined(SHORT_EXT) && !defined(LONG_EXT)
195#define SHORT_EXT ".o"
196#define LONG_EXT "module.o"
197#endif /* !SHORT_EXT && !LONG_EXT */
198
199#endif /* DYNAMIC_LINK */
200
Guido van Rossum6a75d261995-02-18 14:51:15 +0000201/* Max length of module suffix searched for -- accommodates "module.slb" */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000202#ifndef MAXSUFFIXSIZE
Jack Jansen4e043731995-02-13 22:42:34 +0000203#define MAXSUFFIXSIZE 12
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000204#endif
205
206/* Pass it on to import.c */
207int import_maxsuffixsize = MAXSUFFIXSIZE;
208
209struct filedescr import_filetab[] = {
210#ifdef SHORT_EXT
211 {SHORT_EXT, "rb", C_EXTENSION},
212#endif /* !SHORT_EXT */
213#ifdef LONG_EXT
214 {LONG_EXT, "rb", C_EXTENSION},
215#endif /* !LONG_EXT */
216 {".py", "r", PY_SOURCE},
217 {".pyc", "rb", PY_COMPILED},
218 {0, 0}
219};
220
Guido van Rossum38234201996-07-31 17:55:19 +0000221#ifdef NO_DYNAMIC_LINK
222#undef DYNAMIC_LINK
223#endif
224
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000225object *
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000226load_dynamic_module(name, pathname, fp)
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000227 char *name;
228 char *pathname;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000229 FILE *fp;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000230{
231#ifndef DYNAMIC_LINK
232 err_setstr(ImportError, "dynamically linked modules not supported");
233 return NULL;
234#else
235 object *m;
236 char funcname[258];
237 dl_funcptr p = NULL;
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000238#ifdef USE_SHLIB
239 static struct {
240 dev_t dev;
241 ino_t ino;
242 void *handle;
243 } handles[128];
244 static int nhandles = 0;
Guido van Rossum0bbf2531996-08-09 20:55:05 +0000245 char pathbuf[260];
246 if (strchr(pathname, '/') == NULL) {
247 /* Prefix bare filename with "./" */
248 sprintf(pathbuf, "./%-.255s", pathname);
249 pathname = pathbuf;
250 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000251#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000252 sprintf(funcname, FUNCNAME_PATTERN, name);
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000253#ifdef USE_SHLIB
254 if (fp != NULL) {
255 int i;
256 struct stat statb;
257 fstat(fileno(fp), &statb);
258 for (i = 0; i < nhandles; i++) {
259 if (statb.st_dev == handles[i].dev &&
260 statb.st_ino == handles[i].ino) {
261 p = (dl_funcptr) dlsym(handles[i].handle,
262 funcname);
263 goto got_it;
264 }
265 }
266 if (nhandles < 128) {
267 handles[nhandles].dev = statb.st_dev;
268 handles[nhandles].ino = statb.st_ino;
269 }
270 }
271#endif /* USE_SHLIB */
Jack Jansen5d9acb61995-06-14 14:54:25 +0000272#ifdef USE_MAC_DYNAMIC_LOADING
273 /*
274 ** Dynamic loading of CFM shared libraries on the Mac.
275 ** The code has become more convoluted than it was, because we want to be able
276 ** to put multiple modules in a single file. For this reason, we have to determine
277 ** the fragment name, and we cannot use the library entry point but we have to locate
278 ** the correct init routine "by hand".
279 */
Jack Jansen4e043731995-02-13 22:42:34 +0000280 {
281 FSSpec libspec;
282 CFragConnectionID connID;
Guido van Rossum6a75d261995-02-18 14:51:15 +0000283 Ptr mainAddr;
284 Str255 errMessage;
285 OSErr err;
Jack Jansen5d9acb61995-06-14 14:54:25 +0000286 Boolean isfolder, didsomething;
287 char buf[512];
288 Str63 fragname;
289 Ptr symAddr;
290 CFragSymbolClass class;
Jack Jansen4e043731995-02-13 22:42:34 +0000291
Jack Jansen5d9acb61995-06-14 14:54:25 +0000292 /* First resolve any aliases to find the real file */
Jack Jansen4e043731995-02-13 22:42:34 +0000293 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
Jack Jansen5d9acb61995-06-14 14:54:25 +0000294 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
295 if ( err ) {
296 sprintf(buf, "%s: %s", pathname, PyMac_StrError(err));
297 err_setstr(ImportError, buf);
298 return NULL;
299 }
300 /* Next, determine the fragment name, by stripping '.slb' and 'module' */
301 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
302 fragname[0] = libspec.name[0];
303 if( strncmp((char *)(fragname+1+fragname[0]-4), ".slb", 4) == 0 )
304 fragname[0] -= 4;
305 if ( strncmp((char *)(fragname+1+fragname[0]-6), "module", 6) == 0 )
306 fragname[0] -= 6;
307 /* Load the fragment (or return the connID if it is already loaded */
308 err = GetDiskFragment(&libspec, 0, 0, fragname,
Guido van Rossum6a75d261995-02-18 14:51:15 +0000309 kLoadCFrag, &connID, &mainAddr,
310 errMessage);
Jack Jansen4e043731995-02-13 22:42:34 +0000311 if ( err ) {
Guido van Rossum3097c3a1995-02-21 21:02:46 +0000312 sprintf(buf, "%.*s: %s", errMessage[0], errMessage+1, PyMac_StrError(err));
Jack Jansen4e043731995-02-13 22:42:34 +0000313 err_setstr(ImportError, buf);
314 return NULL;
315 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000316 /* Locate the address of the correct init function */
317 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
318 if ( err ) {
319 sprintf(buf, "%s: %s", funcname, PyMac_StrError(err));
320 err_setstr(ImportError, buf);
321 return NULL;
322 }
323 p = (dl_funcptr)symAddr;
Jack Jansen4e043731995-02-13 22:42:34 +0000324 }
Jack Jansen5d9acb61995-06-14 14:54:25 +0000325#endif /* USE_MAC_DYNAMIC_LOADING */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000326#ifdef USE_SHLIB
327 {
328#ifdef RTLD_NOW
329 /* RTLD_NOW: resolve externals now
330 (i.e. core dump now if some are missing) */
331 void *handle = dlopen(pathname, RTLD_NOW);
332#else
333 void *handle;
334 if (verbose)
335 printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
336 handle = dlopen(pathname, RTLD_LAZY);
337#endif /* RTLD_NOW */
338 if (handle == NULL) {
339 err_setstr(ImportError, dlerror());
340 return NULL;
341 }
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000342 if (fp != NULL && nhandles < 128)
343 handles[nhandles++].handle = handle;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000344 p = (dl_funcptr) dlsym(handle, funcname);
345 }
346#endif /* USE_SHLIB */
347#ifdef _AIX
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000348 /*
349 -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
350 -- of the shared module unresolved. Thus we have to resolve them
351 -- explicitely with loadbind. The new module is loaded, then we
352 -- resolve its symbols using the list of already loaded modules
353 -- (only those that belong to the python executable). Get these
354 -- with loadquery(L_GETINFO).
355 */
356 {
357 static void *staticmodlistptr = NULL;
358
359 if (!staticmodlistptr)
360 if (aix_getoldmodules(&staticmodlistptr) == -1)
361 return NULL;
362 p = (dl_funcptr) load(pathname, L_NOAUTODEFER, 0);
363 if (p == NULL) {
364 aix_loaderror(pathname);
365 return NULL;
366 }
367 if (aix_bindnewmodule((void *)p, staticmodlistptr) == -1) {
368 aix_loaderror(pathname);
369 return NULL;
370 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000371 }
372#endif /* _AIX */
373#ifdef NT
374 {
375 HINSTANCE hDLL;
376 hDLL = LoadLibrary(pathname);
377 if (hDLL==NULL){
Guido van Rossum11a3f0c21995-07-18 14:40:09 +0000378 char errBuf[256];
379 unsigned int errorCode;
380
381 /* Get an error string from Win32 error code */
382 char theInfo[256]; /* Pointer to error text from system */
383 int theLength; /* Length of error text */
384
385 errorCode = GetLastError();
386
387 theLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
388 NULL, /* message source */
389 errorCode, /* the message (error) ID */
390 0, /* default language environment */
391 (LPTSTR) theInfo, /* the buffer */
392 sizeof(theInfo), /* the buffer size */
393 NULL); /* no additional format args. */
394
395 /* Problem: could not get the error message. This should not happen if called correctly. */
396 if (theLength == 0) {
397 sprintf(errBuf, "DLL load failed with error code %d", errorCode);
398 } else {
399 int len;
400 /* For some reason a \r\n is appended to the text */
401 if (theLength >= 2 && theInfo[theLength-2] == '\r' && theInfo[theLength-1] == '\n') {
402 theLength -= 2;
403 theInfo[theLength] = '\0';
404 }
405 strcpy(errBuf, "DLL load failed: ");
406 len = strlen(errBuf);
407 strncpy(errBuf+len, theInfo, sizeof(errBuf)-len);
408 errBuf[sizeof(errBuf)-1] = '\0';
409 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000410 err_setstr(ImportError, errBuf);
411 return NULL;
412 }
413 p = GetProcAddress(hDLL, funcname);
414 }
415#endif /* NT */
Guido van Rossumdadc8241996-05-23 22:51:40 +0000416#ifdef WIN16_DL
417 {
418 HINSTANCE hDLL;
419 hDLL = LoadLibrary(pathname);
420 if (hDLL < HINSTANCE_ERROR){
421 char errBuf[256];
422 sprintf(errBuf, "DLL load failed with error code %d", hDLL);
423 err_setstr(ImportError, errBuf);
424 return NULL;
425 }
426 p = GetProcAddress(hDLL, funcname);
427 }
428#endif /* WIN16_DL */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000429#ifdef USE_DL
430 p = dl_loadmod(getprogramname(), pathname, funcname);
431#endif /* USE_DL */
432#ifdef USE_RLD
433 {
434 NXStream *errorStream;
435 struct mach_header *new_header;
436 const char *filenames[2];
437 long ret;
438 unsigned long ptr;
439
440 errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
441 filenames[0] = pathname;
442 filenames[1] = NULL;
443 ret = rld_load(errorStream, &new_header,
444 filenames, NULL);
445
446 /* extract the error messages for the exception */
447 if(!ret) {
448 char *streamBuf;
449 int len, maxLen;
450
451 NXPutc(errorStream, (char)0);
452
453 NXGetMemoryBuffer(errorStream,
454 &streamBuf, &len, &maxLen);
455 err_setstr(ImportError, streamBuf);
456 }
457
458 if(ret && rld_lookup(errorStream, funcname, &ptr))
459 p = (dl_funcptr) ptr;
460
461 NXCloseMemory(errorStream, NX_FREEBUFFER);
462
463 if(!ret)
464 return NULL;
465 }
466#endif /* USE_RLD */
467#ifdef hpux
468 {
469 shl_t lib;
470 int flags;
471
472 flags = BIND_DEFERRED;
473 if (verbose)
474 {
475 flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
476 printf("shl_load %s\n",pathname);
477 }
478 lib = shl_load(pathname, flags, 0);
479 if (lib == NULL)
480 {
481 char buf[256];
482 if (verbose)
483 perror(pathname);
484 sprintf(buf, "Failed to load %.200s", pathname);
485 err_setstr(ImportError, buf);
486 return NULL;
487 }
488 if (verbose)
489 printf("shl_findsym %s\n", funcname);
490 shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
491 if (p == NULL && verbose)
492 perror(funcname);
493 }
494#endif /* hpux */
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000495 got_it:
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000496 if (p == NULL) {
497 err_setstr(ImportError,
498 "dynamic module does not define init function");
499 return NULL;
500 }
501 (*p)();
502
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000503 m = dictlookup(import_modules, name);
504 if (m == NULL) {
505 if (err_occurred() == NULL)
506 err_setstr(SystemError,
507 "dynamic module not initialized properly");
508 return NULL;
509 }
510 if (verbose)
511 fprintf(stderr,
512 "import %s # dynamically loaded from %s\n",
513 name, pathname);
514 INCREF(m);
515 return m;
516#endif /* DYNAMIC_LINK */
517}
518
519
520#ifdef _AIX
521
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000522#include <ctype.h> /* for isdigit() */
523#include <errno.h> /* for global errno */
524#include <string.h> /* for strerror() */
525#include <stdlib.h> /* for malloc(), free() */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000526
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000527typedef struct Module {
528 struct Module *next;
529 void *entry;
530} Module, *ModulePtr;
531
532static int
533aix_getoldmodules(modlistptr)
534 void **modlistptr;
535{
536 register ModulePtr modptr, prevmodptr;
537 register struct ld_info *ldiptr;
538 register char *ldibuf;
539 register int errflag, bufsize = 1024;
540 register unsigned int offset;
541
542 /*
543 -- Get the list of loaded modules into ld_info structures.
544 */
545 if ((ldibuf = malloc(bufsize)) == NULL) {
546 err_setstr(ImportError, strerror(errno));
547 return -1;
548 }
549 while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
550 && errno == ENOMEM) {
551 free(ldibuf);
552 bufsize += 1024;
553 if ((ldibuf = malloc(bufsize)) == NULL) {
554 err_setstr(ImportError, strerror(errno));
555 return -1;
556 }
557 }
558 if (errflag == -1) {
559 err_setstr(ImportError, strerror(errno));
560 return -1;
561 }
562 /*
563 -- Make the modules list from the ld_info structures.
564 */
565 ldiptr = (struct ld_info *)ldibuf;
566 prevmodptr = NULL;
567 do {
568 if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
569 err_setstr(ImportError, strerror(errno));
570 while (*modlistptr) {
571 modptr = (ModulePtr)*modlistptr;
572 *modlistptr = (void *)modptr->next;
573 free(modptr);
574 }
575 return -1;
576 }
577 modptr->entry = ldiptr->ldinfo_dataorg;
578 modptr->next = NULL;
579 if (prevmodptr == NULL)
580 *modlistptr = (void *)modptr;
581 else
582 prevmodptr->next = modptr;
583 prevmodptr = modptr;
584 offset = (unsigned int)ldiptr->ldinfo_next;
585 ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset);
586 } while (offset);
587 free(ldibuf);
588 return 0;
589}
590
591static int
592aix_bindnewmodule(newmoduleptr, modlistptr)
593 void *newmoduleptr;
594 void *modlistptr;
595{
596 register ModulePtr modptr;
597
598 /*
599 -- Bind the new module with the list of loaded modules.
600 */
601 for (modptr = (ModulePtr)modlistptr; modptr; modptr = modptr->next)
602 if (loadbind(0, modptr->entry, newmoduleptr) != 0)
603 return -1;
604 return 0;
605}
606
607static void
608aix_loaderror(pathname)
609 char *pathname;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000610{
611
Guido van Rossum236f62d1996-06-26 21:07:08 +0000612 char *message[1024], errbuf[1024];
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000613 register int i,j;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000614
615 struct errtab {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000616 int errNo;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000617 char *errstr;
618 } load_errtab[] = {
Sjoerd Mullenderfbe6d331995-06-12 15:51:34 +0000619 {L_ERROR_TOOMANY, "too many errors, rest skipped."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000620 {L_ERROR_NOLIB, "can't load library:"},
621 {L_ERROR_UNDEF, "can't find symbol in library:"},
622 {L_ERROR_RLDBAD,
623 "RLD index out of range or bad relocation type:"},
624 {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
625 {L_ERROR_MEMBER,
626 "file not an archive or does not contain requested member:"},
627 {L_ERROR_TYPE, "symbol table mismatch:"},
Guido van Rossum236f62d1996-06-26 21:07:08 +0000628 {L_ERROR_ALIGN, "text alignment in file is wrong."},
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000629 {L_ERROR_SYSTEM, "System error:"},
630 {L_ERROR_ERRNO, NULL}
631 };
632
633#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
634#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
635
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000636 sprintf(errbuf, "from module %.200s ", pathname);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000637
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000638 if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000639 ERRBUF_APPEND(strerror(errno));
Guido van Rossum236f62d1996-06-26 21:07:08 +0000640 ERRBUF_APPEND("\n");
641 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000642 for(i = 0; message[i] && *message[i]; i++) {
643 int nerr = atoi(message[i]);
644 for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
Guido van Rossumd5962ad1996-07-31 22:44:53 +0000645 if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
Guido van Rossum236f62d1996-06-26 21:07:08 +0000646 ERRBUF_APPEND(load_errtab[j].errstr);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000647 }
648 while (isdigit(*message[i])) message[i]++ ;
649 ERRBUF_APPEND(message[i]);
650 ERRBUF_APPEND("\n");
651 }
652 errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
653 err_setstr(ImportError, errbuf);
654 return;
655}
656
657#endif /* _AIX */