home *** CD-ROM | disk | FTP | other *** search
-
- /* Support for dynamic loading of extension modules */
-
- #include "Python.h"
- #include "importdl.h"
-
-
- #ifdef WITH_DYLD
-
- #define USE_DYLD
-
- #include <mach-o/dyld.h>
-
- #else /* WITH_DYLD */
-
- #define USE_RLD
- /* Define this to 1 if you want be able to load ObjC modules as well:
- it switches between two different way of loading modules on the NeXT,
- one that directly interfaces with the dynamic loader (rld_load(), which
- does not correctly load ObjC object files), and another that uses the
- ObjC runtime (objc_loadModules()) to do the job.
- You'll have to add ``-ObjC'' to the compiler flags if you set this to 1.
- */
- #define HANDLE_OBJC_MODULES 1
- #if HANDLE_OBJC_MODULES
- #include <objc/Object.h>
- #include <objc/objc-load.h>
- #endif
-
- #include <mach-o/rld.h>
-
- #endif /* WITH_DYLD */
-
-
- const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".so", "rb", C_EXTENSION},
- {"module.so", "rb", C_EXTENSION},
- {0, 0}
- };
-
- dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
- {
- dl_funcptr p = NULL;
- char funcname[258];
-
- sprintf(funcname, "_init%.200s", shortname);
-
- #ifdef USE_RLD
- {
- NXStream *errorStream;
- struct mach_header *new_header;
- const char *filenames[2];
- long ret;
- unsigned long ptr;
-
- errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- filenames[0] = pathname;
- filenames[1] = NULL;
-
- #if HANDLE_OBJC_MODULES
-
- /* The following very bogus line of code ensures that
- objc_msgSend, etc are linked into the binary. Without
- it, dynamic loading of a module that includes objective-c
- method calls will fail with "undefined symbol _objc_msgSend()".
- This remains true even in the presence of the -ObjC flag
- to the compiler
- */
-
- [Object name];
-
- /* objc_loadModules() dynamically loads the object files
- indicated by the paths in filenames. If there are any
- errors generated during loading -- typically due to the
- inability to find particular symbols -- an error message
- will be written to errorStream.
- It returns 0 if the module is successfully loaded, 1
- otherwise.
- */
-
- ret = !objc_loadModules(filenames, errorStream,
- NULL, &new_header, NULL);
-
- #else /* !HANDLE_OBJC_MODULES */
-
- ret = rld_load(errorStream, &new_header,
- filenames, NULL);
-
- #endif /* HANDLE_OBJC_MODULES */
-
- /* extract the error messages for the exception */
- if(!ret) {
- char *streamBuf;
- int len, maxLen;
-
- NXPutc(errorStream, (char)0);
-
- NXGetMemoryBuffer(errorStream,
- &streamBuf, &len, &maxLen);
- PyErr_SetString(PyExc_ImportError, streamBuf);
- }
-
- if(ret && rld_lookup(errorStream, funcname, &ptr))
- p = (dl_funcptr) ptr;
-
- NXCloseMemory(errorStream, NX_FREEBUFFER);
-
- if(!ret)
- return NULL;
- }
- #endif /* USE_RLD */
- #ifdef USE_DYLD
- /* This is also NeXT-specific. However, frameworks (the new style
- of shared library) and rld() can't be used in the same program;
- instead, you have to use dyld, which is mostly unimplemented. */
- {
- NSObjectFileImageReturnCode rc;
- NSObjectFileImage image;
- NSModule newModule;
- NSSymbol theSym;
- void *symaddr;
- const char *errString;
-
- rc = NSCreateObjectFileImageFromFile(pathname, &image);
- switch(rc) {
- default:
- case NSObjectFileImageFailure:
- NSObjectFileImageFormat:
- /* for these a message is printed on stderr by dyld */
- errString = "Can't create object file image";
- break;
- case NSObjectFileImageSuccess:
- errString = NULL;
- break;
- case NSObjectFileImageInappropriateFile:
- errString = "Inappropriate file type for dynamic loading";
- break;
- case NSObjectFileImageArch:
- errString = "Wrong CPU type in object file";
- break;
- NSObjectFileImageAccess:
- errString = "Can't read object file (no access)";
- break;
- }
- if (errString == NULL) {
- newModule = NSLinkModule(image, pathname, TRUE);
- if (!newModule)
- errString = "Failure linking new module";
- }
- if (errString != NULL) {
- PyErr_SetString(PyExc_ImportError, errString);
- return NULL;
- }
- if (!NSIsSymbolNameDefined(funcname)) {
- /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
- NSUnLinkModule(newModule, FALSE);
- PyErr_Format(PyExc_ImportError,
- "Loaded module does not contain symbol %.200s",
- funcname);
- return NULL;
- }
- theSym = NSLookupAndBindSymbol(funcname);
- p = (dl_funcptr)NSAddressOfSymbol(theSym);
- }
- #endif /* USE_DYLD */
-
- return p;
- }
-