1 2 /* Support for dynamic loading of extension modules on Mac OS X 3 ** All references to "NeXT" are for historical reasons. 4 */ 5 6 #include "Python.h" 7 #include "importdl.h" 8 9 #include <mach-o/dyld.h> 10 11 const struct filedescr _PyImport_DynLoadFiletab[] = { 12 {".so", "rb", C_EXTENSION}, 13 {"module.so", "rb", C_EXTENSION}, 14 {0, 0} 15 }; 16 17 /* 18 ** Python modules are Mach-O MH_BUNDLE files. The best way to load these 19 ** is each in a private namespace, so you can load, say, a module bar and a 20 ** module foo.bar. If we load everything in the global namespace the two 21 ** initbar() symbols will conflict. 22 ** However, it seems some extension packages depend upon being able to access 23 ** each others' global symbols. There seems to be no way to eat our cake and 24 ** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour 25 ** you get. 26 */ 27 28 #ifdef USE_DYLD_GLOBAL_NAMESPACE 29 #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR 30 #else 31 #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \ 32 NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE 33 #endif 34 dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, 35 const char *pathname, FILE *fp) 36 { 37 dl_funcptr p = NULL; 38 char funcname[258]; 39 NSObjectFileImageReturnCode rc; 40 NSObjectFileImage image; 41 NSModule newModule; 42 NSSymbol theSym; 43 const char *errString; 44 char errBuf[512]; 45 46 PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname); 47 48 #ifdef USE_DYLD_GLOBAL_NAMESPACE 49 if (NSIsSymbolNameDefined(funcname)) { 50 theSym = NSLookupAndBindSymbol(funcname); 51 p = (dl_funcptr)NSAddressOfSymbol(theSym); 52 return p; 53 } 54 #endif 55 rc = NSCreateObjectFileImageFromFile(pathname, &image); 56 switch(rc) { 57 default: 58 case NSObjectFileImageFailure: 59 case NSObjectFileImageFormat: 60 /* for these a message is printed on stderr by dyld */ 61 errString = "Can't create object file image"; 62 break; 63 case NSObjectFileImageSuccess: 64 errString = NULL; 65 break; 66 case NSObjectFileImageInappropriateFile: 67 errString = "Inappropriate file type for dynamic loading"; 68 break; 69 case NSObjectFileImageArch: 70 errString = "Wrong CPU type in object file"; 71 break; 72 case NSObjectFileImageAccess: 73 errString = "Can't read object file (no access)"; 74 break; 75 } 76 if (errString == NULL) { 77 newModule = NSLinkModule(image, pathname, LINKOPTIONS); 78 if (newModule == NULL) { 79 int errNo; 80 const char *fileName, *moreErrorStr; 81 NSLinkEditErrors c; 82 NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr ); 83 PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s", 84 fileName, moreErrorStr); 85 errString = errBuf; 86 } 87 } 88 if (errString != NULL) { 89 PyErr_SetString(PyExc_ImportError, errString); 90 return NULL; 91 } 92 #ifdef USE_DYLD_GLOBAL_NAMESPACE 93 if (!NSIsSymbolNameDefined(funcname)) { 94 /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */ 95 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */ 96 PyErr_Format(PyExc_ImportError, 97 "Loaded module does not contain symbol %.200s", 98 funcname); 99 return NULL; 100 } 101 theSym = NSLookupAndBindSymbol(funcname); 102 #else 103 theSym = NSLookupSymbolInModule(newModule, funcname); 104 if ( theSym == NULL ) { 105 /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */ 106 PyErr_Format(PyExc_ImportError, 107 "Loaded module does not contain symbol %.200s", 108 funcname); 109 return NULL; 110 } 111 #endif 112 p = (dl_funcptr)NSAddressOfSymbol(theSym); 113 return p; 114 } 115