You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.4 KiB
114 lines
3.4 KiB
|
|
/* Support for dynamic loading of extension modules on Mac OS X |
|
** All references to "NeXT" are for historical reasons. |
|
*/ |
|
|
|
#include "Python.h" |
|
#include "importdl.h" |
|
|
|
#include <mach-o/dyld.h> |
|
|
|
const struct filedescr _PyImport_DynLoadFiletab[] = { |
|
{".so", "rb", C_EXTENSION}, |
|
{"module.so", "rb", C_EXTENSION}, |
|
{0, 0} |
|
}; |
|
|
|
/* |
|
** Python modules are Mach-O MH_BUNDLE files. The best way to load these |
|
** is each in a private namespace, so you can load, say, a module bar and a |
|
** module foo.bar. If we load everything in the global namespace the two |
|
** initbar() symbols will conflict. |
|
** However, it seems some extension packages depend upon being able to access |
|
** each others' global symbols. There seems to be no way to eat our cake and |
|
** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour |
|
** you get. |
|
*/ |
|
|
|
#ifdef USE_DYLD_GLOBAL_NAMESPACE |
|
#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR |
|
#else |
|
#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \ |
|
NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE |
|
#endif |
|
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, |
|
const char *pathname, FILE *fp) |
|
{ |
|
dl_funcptr p = NULL; |
|
char funcname[258]; |
|
NSObjectFileImageReturnCode rc; |
|
NSObjectFileImage image; |
|
NSModule newModule; |
|
NSSymbol theSym; |
|
const char *errString; |
|
char errBuf[512]; |
|
|
|
PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname); |
|
|
|
#ifdef USE_DYLD_GLOBAL_NAMESPACE |
|
if (NSIsSymbolNameDefined(funcname)) { |
|
theSym = NSLookupAndBindSymbol(funcname); |
|
p = (dl_funcptr)NSAddressOfSymbol(theSym); |
|
return p; |
|
} |
|
#endif |
|
rc = NSCreateObjectFileImageFromFile(pathname, &image); |
|
switch(rc) { |
|
default: |
|
case NSObjectFileImageFailure: |
|
case 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; |
|
case NSObjectFileImageAccess: |
|
errString = "Can't read object file (no access)"; |
|
break; |
|
} |
|
if (errString == NULL) { |
|
newModule = NSLinkModule(image, pathname, LINKOPTIONS); |
|
if (newModule == NULL) { |
|
int errNo; |
|
const char *fileName, *moreErrorStr; |
|
NSLinkEditErrors c; |
|
NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr ); |
|
PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s", |
|
fileName, moreErrorStr); |
|
errString = errBuf; |
|
} |
|
} |
|
if (errString != NULL) { |
|
PyErr_SetString(PyExc_ImportError, errString); |
|
return NULL; |
|
} |
|
#ifdef USE_DYLD_GLOBAL_NAMESPACE |
|
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); |
|
#else |
|
theSym = NSLookupSymbolInModule(newModule, funcname); |
|
if ( theSym == NULL ) { |
|
NSUnLinkModule(newModule, FALSE); |
|
PyErr_Format(PyExc_ImportError, |
|
"Loaded module does not contain symbol %.200s", |
|
funcname); |
|
return NULL; |
|
} |
|
#endif |
|
p = (dl_funcptr)NSAddressOfSymbol(theSym); |
|
return p; |
|
}
|
|
|