PageRenderTime 414ms CodeModel.GetById 201ms app.highlight 7ms RepoModel.GetById 204ms app.codeStats 0ms

/Python/dynload_next.c

http://unladen-swallow.googlecode.com/
C | 114 lines | 89 code | 8 blank | 17 comment | 10 complexity | 6df9b0ef3982aee5a6c721296010162e MD5 | raw file
  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
 11const 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
 34dl_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}