| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | /* Support for dynamic loading of extension modules on Mac OS X
 | 
					
						
							|  |  |  | ** All references to "NeXT" are for historical reasons. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  | ** 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
 | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | 					const char *pathname, FILE *fp) | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	dl_funcptr p = NULL; | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | 	char funcname[258]; | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 	NSObjectFileImageReturnCode rc; | 
					
						
							|  |  |  | 	NSObjectFileImage image; | 
					
						
							|  |  |  | 	NSModule newModule; | 
					
						
							|  |  |  | 	NSSymbol theSym; | 
					
						
							|  |  |  | 	const char *errString; | 
					
						
							|  |  |  | 	char errBuf[512]; | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | 	PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | #ifdef USE_DYLD_GLOBAL_NAMESPACE
 | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 	if (NSIsSymbolNameDefined(funcname)) { | 
					
						
							|  |  |  | 		theSym = NSLookupAndBindSymbol(funcname); | 
					
						
							|  |  |  | 		p = (dl_funcptr)NSAddressOfSymbol(theSym); | 
					
						
							|  |  |  | 		return p; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 	rc = NSCreateObjectFileImageFromFile(pathname, &image); | 
					
						
							|  |  |  | 	switch(rc) { | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 		case NSObjectFileImageFailure: | 
					
						
							|  |  |  | 		case NSObjectFileImageFormat: | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | 			/* for these a message is printed on stderr by dyld */ | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 			errString = "Can't create object file image"; | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 		case NSObjectFileImageSuccess: | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 			errString = NULL; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 		case NSObjectFileImageInappropriateFile: | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 			errString = "Inappropriate file type for dynamic loading"; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 		case NSObjectFileImageArch: | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 			errString = "Wrong CPU type in object file"; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 		case NSObjectFileImageAccess: | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 			errString = "Can't read object file (no access)"; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (errString == NULL) { | 
					
						
							|  |  |  | 		newModule = NSLinkModule(image, pathname, LINKOPTIONS); | 
					
						
							|  |  |  | 		if (newModule == NULL) { | 
					
						
							|  |  |  | 			int errNo; | 
					
						
							| 
									
										
										
										
											2002-12-23 21:03:36 +00:00
										 |  |  | 			const char *fileName, *moreErrorStr; | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 			NSLinkEditErrors c; | 
					
						
							|  |  |  | 			NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr ); | 
					
						
							|  |  |  | 			PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",  | 
					
						
							|  |  |  | 					fileName, moreErrorStr); | 
					
						
							|  |  |  | 			errString = errBuf; | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (errString != NULL) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ImportError, errString); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | #ifdef USE_DYLD_GLOBAL_NAMESPACE
 | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 	if (!NSIsSymbolNameDefined(funcname)) { | 
					
						
							|  |  |  | 		/* UnlinkModule() isn't implemented in current versions, but calling it does no harm */ | 
					
						
							| 
									
										
										
										
											2004-07-15 22:28:48 +00:00
										 |  |  | 		/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */ | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 		PyErr_Format(PyExc_ImportError, | 
					
						
							|  |  |  | 				 "Loaded module does not contain symbol %.200s", | 
					
						
							|  |  |  | 				 funcname); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	theSym = NSLookupAndBindSymbol(funcname); | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 	theSym = NSLookupSymbolInModule(newModule, funcname); | 
					
						
							|  |  |  | 	if ( theSym == NULL ) { | 
					
						
							| 
									
										
										
										
											2004-07-15 22:28:48 +00:00
										 |  |  | 		/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */ | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | 		PyErr_Format(PyExc_ImportError, | 
					
						
							|  |  |  | 				 "Loaded module does not contain symbol %.200s", | 
					
						
							|  |  |  | 				 funcname); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2002-02-01 16:01:05 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-02-01 22:24:56 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	p = (dl_funcptr)NSAddressOfSymbol(theSym); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	return p; | 
					
						
							|  |  |  | } |